简体   繁体   中英

C - memory allocation issue - need explanation

Recently, I have encountered a problem with C pointers. As you might see, I've got a loop that reads data from STDIN. The problem is I don't quite understand what I've done.

I allocated memory for this struct_CONTAINER structure. I desired to have an array of c-strings with BUFFER_SIZE length inside it. If I understand correctly, this array contains BUFFER_SIZE (char *) objects - and that means that the weight of this array would be 8 * BUFFER_SIZE bytes (8 bytes at most for each char pointer). So, for example, if BUFFER_SIZE is defined with value 10, then that gives us 80 bytes for this array and probably the whole structure would have a similar size.

The problem is I am able to iterate over that pointer with values greater than BUFFER_SIZE and what is weird for me - that memory is not NULL. I know that in that loop I might be trying to access some other already allocated memory. But I'm not sure. If somebody would be nice and told me what I am doing right and wrong. It's possible that the memory allocation is too large. Thanks in advance!

char *item = NULL;

if( dup2( STDIN_FILENO, fdin ) < 0 ){
    perror( "dup2(  )" );
    exit( errno );
}

memset( reading, '\0', BUFFER_SIZE );

struct struct_CONTAINER{
    char *container[BUFFER_SIZE];
};


while( ( r_control = read( fdin, reading, BUFFER_SIZE-1 ) ) > 0 ){
    item = &shmemContainer->container[i++];
    strcpy(item, reading);
    memset( reading, '\0', BUFFER_SIZE );
}

EDIT: I forgot to show you what is the type of "item" variable

Your struct member container is of char* type means its array of strings. you are assigning to item address of string that char** and try to call strcpy(item, reading);

You are doing wrong at-least in one of following statments.

 item = &shmemContainer->container[i++];
        ^   is wrong 
 strcpy(item, reading);
         ^ or this is wrong

[ANSWER] ( as you commented first point is error in your code )
Because precedence of -> operator is higher then & . You should get a warning when you compile your code.

  • if first expression item = &shmemContainer->container[i++]; is wrong write it like:

    item = (&shmemContainer)->container[i++];

  • and if strcpy(item, reading); is wrong correct it like:

    strcpy(*item, reading);

And as I can understand from your while loop you wants to read string from fdin into string array and you can do like:

while( ( r_control = read( fdin, reading, BUFFER_SIZE-1 ) ) > 0 ){
    reading[r_control] = '\0'; // null ternimate
    strcpy(shmemContainer->container[i++],reading) ;
    memset( reading, '\0', BUFFER_SIZE );
}

code reading[r_control] = '\\0'; added this because first time you are missing memset() , remember read() doesn't terminate \\0 string it self.

EDIT :
Consider @Digikata's comment because you are doing strcpy() to container[] be sure that you allocate memory for each string.

My suggestion:

container[] is array of string so you can allocate memory in your while loop, like:

i = 0;
while( ( r_control = read( fdin, reading, BUFFER_SIZE-1 ) ) > 0 ){
    reading[r_control] = '\0'; // null ternimate
    shmemContainer->container[i] = malloc(strlen(reading) + 1);
    strcpy(shmemContainer->container[i++],reading) ;
    memset( reading, '\0', BUFFER_SIZE );
}

Added memory allocation if you are missing.

C doesn't prevent you from indexing past the the intended memory location. For example:

char astring[5] = "0123";  // there is a zero at index 4 
char* ptr = astring;       // ptr[4] == 0

printf("%c", ptr[5]);  // reads a byte beyond the end of the string array 

Your code needs to logically prevent that from occurring, as there is frequently data there, but writing it (and sometimes even reading it) will result in undefined behavior. So in your code, it's normal for the area beyond your container to read as not NULL.

BTW, it's not clear from your question if you understand the difference between a char* type pointing to a c-string and the allocated memory area for example the "ptr" the "astring" variable in the code above. Your sample code doesn't allocate any memory for the string.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM