简体   繁体   中英

Short & Quick malloc memory access issue

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
    char **wordlist=(char **)malloc(sizeof(char*)*4);
    for(int i=0;i<4;i++)
    {
        char *word=(char*)malloc(sizeof(char*)*20);;
        scanf("%s",word);
        wordlist[i]=word;
        free(word);
    }
    for(int i=0;i<4;i++)
    {
        printf("at %d value is %s\n",i,wordlist[i]);
    }
    free(wordlist);
    return 0;
}

So the issue is as follows: I can run this code as many times as I want, and when it reads back the array I get COMPLETELY random results when it comes to where things are stored. Example: If input was "foo bar is great" it would output any combination of the following "value at 0 is bar value at 1 is bar value at 2 is great value at 3 is foo"

Part of a much larger program, but this is the concept i'm struggling to find a solution (or proper implementation) to. :( I have searched google high and low, as well as this site, with no solution that works properly. Any help is appreciated!

The program is wrong and has memory leaks.

For example in this statement

char *word=(char*)malloc(sizeof(char*)*20);;
                         ^^^^^^^^^^^^^ 

there is used sizeof( char * ) instead of sizeof( char )

Then after these statements

 wordlist[i]=word;
 free(word);

wordlist[I] will point to memory that was deleted.

As result the program has undefined behavior.

What you need is something like the following

#include <stdio.h>
#include <stdlib.h>

#define N   4
#define M   20

int main( void )
{
    char ( *wordlist )[M] = malloc( sizeof( char[N][M] ) );

    for ( size_t i = 0; i < N; i++ )
    {
        scanf( "%19s", wordlist[i] );
    }

    for ( size_t i = 0; i < N; i++ )
    {
        printf( "at %zu value is %s\n", i, wordlist[i] );
    }

    free( wordlist );

    return 0;
}

For example if to enter

one two free four

then the output will look like

at 0 value is one
at 1 value is two
at 2 value is free
at 3 value is four

Take into account that if your compiler supports variable length arrays then there is not necessary that the right-most dimension would be a constant.

Another approach is to allocate dynamically an array of pointers to first elements of one-dimensional character arrays. For example

#include <stdio.h>
#include <stdlib.h>

#define N   4
#define M   20

int main( void )
{
    char **wordlist = malloc( sizeof( char *[N] ) );

    for ( size_t i = 0; i < N; i++ )
    {
        wordlist[i] = malloc( sizeof( char[M] ) );
        scanf( "%19s", wordlist[i] );
    }

    for ( size_t i = 0; i < N; i++ )
    {
        printf( "at %zu value is %s\n", i, wordlist[i] );
    }


    for ( size_t i = 0; i < N; i++ ) free( wordlist[i] );

    free( wordlist );

    return 0;
}

The result will be the same as for the preceding program. However in this case instead to allocate only one two-dimensional array there are allocated several one-dimensional arrays.

You free each one of your words before actually printing it. What you need to do is in the end(that is after the priniting -could be in the printing loop)

for (i=0;i<4;i++)
   free(wordlist[i]);
free(wordlist) 

and remove free(word); in the first loop

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