存储文件内容的二维数组中可能存在内存损坏

时间:2013-11-26 07:48:54

标签: c multidimensional-array

我已经能够解决大部分问题,但是我遇到了一些我不确定如何解决的问题。

让我解释一下:我有一个示例文件,其中包含小写字母到长度为2的所有非独特组合(即aa, ab, ac, ad...)。因此,非独特组合的总数为26 ^ 2,676。

知道这非常有用,因为我知道有676行,每行包含一个长度为2的字符串。

以下是代码:

#include <stdlib.h>
#include <string.h>

int main(){

    FILE* file;
    //These would be passed as function arguments
    int lines = 676;
    int sLength = 2;

    int C = lines+1;
    int R = sLength+2;
    int i,j; //Dummy indices
    int len;

    //Create 2-D array on the heap
    char** mystring = (char**) malloc(C*sizeof(char*));
    for(i = 0; i<C; i++) mystring[i] = (char *) malloc(R*sizeof(char)); //Need to free each element individually later on

   //Create temporary char array
   char line[R];

   //Open file to read and store values
   file = fopen("alphaLow2.txt", "r");
   if(file == NULL) perror("Error opening file");
   else{
        i = 0;
        while(fgets(line, sizeof(line), file) != NULL){
                  //Remove next line
                  len = strlen(line);
                  if((line[len-1]) == '\n') (line[len-1]) = '\0';
                  len--; //Decrement length by one because of replacing EOL with null terminator     

                  //Copy character set
                  strcpy(mystring[i], line); //NOT certain if this works being that mystring is 2-D
                  i++;
       }
       mystring[C] = '\0'; //Append null terminator
   }
   for(i = 0; mystring[i]; i++){
     for(j = 0; mystring[i][j]; j++){
           printf("%c", mystring[i][j]);
     }
   }
   getchar();
   return 0;
}

进一步解释,int C = lines+1以附加空终止符。 int R = sLength+2以便考虑文件中存在的\n,以及fgets()始终添加空终止符的事实。因此,在此示例中,数组的大小应为mystring[C][R] - &gt; mystring[677][4]。 while循环将\n替换为\0。打印输出是正确的,但在打印输出的最后,有一个奇数字符串:

enter image description here

zz之后的字符不应该在那里。这让我想知道我的程序中是否存在某些内存损坏。也许我的阵列不够大?我不确定。否则,其他所有内容似乎都能正常运行。

另外,我将在最终节目中释放内存。现在,我正试图让它正常工作。我也知道有更简单的方法可以做到这一点。例如,std::string array会使这更容易。但是,我正在将此阵列复制到启用cuda的设备,而cuda无法识别该格式。

赞赏任何有建设性的意见。

2 个答案:

答案 0 :(得分:1)

您的mystring数组中没有终止NULL条目,因此您的

for(i = 0; mystring[i]; i++)

最终会读得太多。 可能会导致您的麻烦。

答案 1 :(得分:1)

mystringchar**,因此此调用mystring[C] = '\0'不太正确。 mystring[C]char*,因此您不应为其指定char值。在这种情况下代码可以工作,因为\0为0而NULL也为0.您可以做的是用mystring[C-1] = NULL替换此调用。

此外,您还为mystring的最后一行指定了NULL,但不能保证文件始终具有C - 1行(因此,如果您为mystring[C-1]分配NULL,则可以确定所有以前的行都有已被阅读)。最好在循环读取行中添加一个计数器,并为mystring中的下一行指定NULL。

如上面评论中所述,mystring[C]超出了mystring,因此您应将C替换为C - 1