【问题标题】:Short & Quick malloc memory access issue短而快的 malloc 内存访问问题
【发布时间】:2016-05-17 02:40:36
【问题描述】:
#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;
}

所以问题如下:我可以根据需要多次运行此代码,当它读回数组时,当涉及到存储位置时,我会得到完全随机的结果。示例:如果输入是“foo bar is great”,它将输出以下“0 处的值是 1 处的 bar 值是 2 处的 bar 值是 3 处的大值是 foo”的任意组合

一个更大的程序的一部分,但这是我正在努力寻找解决方案(或正确实施)的概念。 :( 我已经搜索了谷歌的高低,以及这个网站,没有任何解决方案可以正常工作。感谢任何帮助!

【问题讨论】:

  • wordlist[i]=word; free(word); 你认为这有什么作用?该行中的printf("at %d value is %s\n",i,wordlist[i]); wordlist[i] 指向已释放的内存。访问释放的内存是未定义的行为(正如您亲身发现的那样)。

标签: c arrays pointers multidimensional-array malloc


【解决方案1】:

在实际打印之前释放每个单词。 你需要做的是最后(即在打印之后 - 可能在打印循环中)

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

并在第一个循环中删除free(word);

【讨论】:

    【解决方案2】:

    程序错误,内存泄漏。

    例如在这个语句中

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

    这里用sizeof( char * )代替sizeof( char )

    然后在这些语句之后

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

    wordlist[I] 将指向已删除的内存。

    因此程序具有未定义的行为。

    你需要的是类似下面的东西

    #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;
    }
    

    例如如果输入

    one two free four
    

    那么输出会是这样的

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

    请注意,如果您的编译器支持可变长度数组,那么最右边的维度不一定是常量。

    另一种方法是动态分配一个指针数组,指向一维字符数组的第一个元素。 例如

    #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;
    }
    

    结果将与前面的程序相同。然而,在这种情况下,为了只分配一个二维数组,而是分配了几个一维数组。

    【讨论】:

    • @Nelson 完全没有。:)
    猜你喜欢
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    • 2020-06-22
    • 1970-01-01
    • 2019-04-28
    • 1970-01-01
    • 2020-04-09
    • 2016-09-27
    相关资源
    最近更新 更多