Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!


1 Answers

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.

like image 179
Vlad from Moscow Avatar answered Dec 06 '25 03:12

Vlad from Moscow



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!