【问题标题】:C 2D arrays of string of unknown length, Crashing when accessing the elements未知长度字符串的C 2D数组,访问元素时崩溃
【发布时间】:2018-07-31 23:14:22
【问题描述】:

所以我一直遇到这个错误,到目前为止我似乎无法找到答案,如果之前有人问过这个问题,我深表歉意。 以下是受影响的代码:

char **List_Of_Words;
int List_Index=0;

List_Of_Words = malloc(Number_of_Words *sizeof(char*));

//Processed_Word word is a word that has been read from a file, its in a loop.
strcpy(*List_Of_Words[List_Index], Processed_Word);
List_Index++;


//im looping through the array to print each word thats stored there
 for(int i = 0;i < List_Index; i++)
{
printf("%s\n", *List_Of_Words[List_Index]);
} 

当我使用 Visual Studio 进行调试时,我收到此错误:

Unhandled exception at 0x01229240 in Wordcount.exe: 0xC0000005: Access violation writing location 0x00000030.

所以,我假设我的程序正在尝试访问它无法访问的内存。 C 对我来说是一门新语言,所以我真的不知道如何处理这个问题。

【问题讨论】:

  • List_Of_Words 是一个指针。但你似乎从来没有真正指出任何地方?
  • 忘记放 malloc 行了
  • List_Of_Words[0] 未初始化,但您取消引用它
  • 另外你给printf("%s"提供了错误的类型,好的编译器会警告这一点
  • 为什么问题标题中有“2D”?对我来说,这看起来像是您尝试拥有一个一维字符串数组。

标签: c multidimensional-array c-strings


【解决方案1】:

您说“//Processed_Word 单词是从文件中读取的单词,它处于循环中。” - 希望您在循环中没有 List_of_Words malloc。我希望您在读取单词一次的循环之外执行此操作

另外,我希望您为 List_of_Words 中的每个条目分配内存,但您似乎没有这样做。

像您尝试创建的那样的二维数组实际上是一个一维数组(一维),它包含对其他一维数组(第二维)的引用。内容单元格存在于其他一维数组中(如果有多个数组,则为最后一维数组)。

【讨论】:

    【解决方案2】:

    您的代码存在许多问题。

    您首先没有分配足够的内存。 List_Of_Words 需要为每个单词分配足够的内存,这很好。但是每个List_Of_Words[] 也需要分配内存来包含这些单词。

    那么你正在这样做,这是错误的,因为你传入 char 作为第一个参数,而不是 char *

    strcpy(*List_Of_Words[List_Index], Processed_Word);
    

    修复这个和之前的问题,你的代码应该是这样的

    List_Of_Words[List_Index]=malloc(strlen(Processed_Word)+1);
    strcpy(List_Of_Words[List_Index], Processed_Word);
    

    或者如果可以的话,您可以使用strdup,它将这两行合二为一

    List_Of_Words[List_Index]=strdup(Processed_Word);
    

    在打印出字符串时也重复了过度取消引用的问题,所以它应该看起来像

    printf("%s\n", List_Of_Words[i]);
    

    当然,除非您只是打印出第一个字符,在这种情况下您应该使用%c 格式化代码。

    【讨论】:

    • 在复制单词之前分配内存不再使程序崩溃,但 printf 行仍然导致问题,它还没有过去..
    • 实际上,NVM 是在重新启动编译器后开始打印,但它只打印出 NULL 而不是每个单独的单词
    • 啊……我刚刚注意到你还有什么做错了——你在那里有List_Index而不是i
    【解决方案3】:

    这里的问题是您已经定义了 List_Of_Words 是什么,但忘记为其分配内存。

    令 r = 您想要存储在 List_Of_Words 中的单词总数。

    以下代码行分配 r 个数据类型为 char* 的块,其中每个块将包含一个单词。

    char **List_Of_Words = (char **)malloc(r * sizeof(char *));
    

    以下代码行分配 c 个数据类型 char 的块,其中每个块将保存一个字符并将数据存储在其中。这里c是要存储的processed_word的大小。

    Inside the loop:
        int c = strlen(processed_word) + 1
        List_Of_Words[i] = (char *)malloc(c * sizeof(char));
        strcpy(List_Of_Words[i], processed_word);
    

    【讨论】:

      【解决方案4】:

      这一行

      strcpy(*List_Of_Words[List_Index], Processed_Word);
      

      不为副本分配内存,它假定您已经分配了足够的空间。如果您的系统有strdup,您可以使用它来分配和复制字符串(但是,strdup 不可移植 - 它不在 C 标准或 Posix 标准中)。

      List_Of_Words[List_Index] = strdup(Processed_Word);
      

      如果你没有strdup,在做strcpy之前分配内存。

      List_of_Words[List_Index] = malloc(strlen(Processed_Word) + 1); // + 1 for the \0 at the end
      strcpy(List_Of_Words[List_Index], Processed_Word);
      

      还要注意,使用下标与取消引用相同。 List_of_Words[index]char* 即它已经是您想要的字符串。 *List_of_Words[index]char,即它是 List_of_Words[index] 处字符串的第一个字符。将char 视为指针只会导致麻烦。您需要在代码中每次使用 *List_of_Words[...] 时删除 * 前缀

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-12-28
        • 2020-10-01
        • 2013-01-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多