sidPhoenix
sidPhoenix

Reputation: 25

Same structure objects memory overlap?

struct integer
{
    int len;
    char* str;
    int* arr;
}int1, int2;


int main(void) {
    printf("Please enter 1st number\n");
    int1.str= str_input();
    int1.len=chars_read-1;
    int1.arr= func2(int1.len, int1.str);
    printf(("\%c\n"), *int1.str);
    printf("Please enter 2nd number\n");
    int2.str = str_input();
    int2.len=chars_read-1;
    printf(("\n %c\n"), *int1.str );
    int2.arr= func2(int2.len, int2.str);

if the input is 4363 and 78596 , the output is 4 and 7 respectively.

The output is not 4 and 4. Given that both are different objects, shouldn't both have different memory allocation?

Please note: this is NOT a typographical error. I have used the same *int1.str both times. the problem is that although I have made no changes in it, its value is changing. How? I do not think that str_input() can make a difference.

char* str_input(void) {
char cur_char;
char* input_ptr = (char*)malloc(LINE_LEN * sizeof(char));
char input_string[LINE_LEN];
//while ((cur_char = getchar()) != '\n' && cur_char<='9' && cur_char>='0' && chars_read < 10000)
for(chars_read=1; chars_read<10000; chars_read++)
{
    scanf("%c", &cur_char);
    if(cur_char!='\n' && cur_char<='9' && cur_char>='0')
    {
        input_string[chars_read-1]= cur_char;
        printf("%c\n", input_string[chars_read-1]);
    }
    else{
            break;
    }
}
input_string[chars_read] = '\n';
input_ptr = &input_string[0]; /* sets pointer to address of 0th index */
return input_ptr;
}

//chars_read is a global variable.

Thanks in advance.

Upvotes: 0

Views: 324

Answers (2)

Eric Postpischil
Eric Postpischil

Reputation: 223494

As noted elsewhere, both of the printf calls in your question pass *int1.str to printf.

However, if that is merely a typographical error in your question, and the second printf call passes *int2.str, then most likely the problem is that str_input returns the address of a fixed buffer (with static or, worse, automatic storage duration). Instead, str_input should use malloc or strdup to allocate new memory for each string and should return a pointer to that. Then the caller should free the memory.

Alternatively, str_input may be changed to accept a buffer and size passed to it by the caller, and the caller will have the responsibility of providing a different buffer for each call.

About the newly posted code

The code for str_input contains this line:

char* input_ptr = (char*)malloc(LINE_LEN * sizeof(char));

That declares input_ptr to be a char * and calls malloc to get space. Then input_ptr is set to contain the address of that space. Later, str_input contains this line:

input_ptr = &input_string[0];

That line completely ignores the prior value of input_ptr and overwrites it with the address of input_string[0]. So the address returned by malloc is gone. The str_input function returns the address of input_string[0] each time it is called. This is wrong. str_input must return the address of the allocated space each time.

Typically, a routine like this would use input_ptr throughout, doing its work in the char array at that address. It would not use a separate array, input_string, for its work. So delete the definition of input_string and change str_input to do all its work in the space pointed to by input_ptr.

Also, do not set the size of the buffer to LINE_LEN in one place but limit the number of characters in it with chars_read < 10000. Use the same limit in all places. Also allow one byte for a null character at the end (unless you are very careful never to perform any operation that requires a null byte at the end).

Upvotes: 2

Miguel Prz
Miguel Prz

Reputation: 13792

you have printed the same variable, *int1.str

It will be helpful have the source code of str_input(), but it's probably that it returns a pointer to the same buffer in each call, so the second call to str_input() updates also the target of int1.str (beacuse it's pointing to the same char* than int2.str)

Upvotes: 2

Related Questions