动态创建字符串数组出错

Error in dynamic creation of string array

我正在尝试从文件中读取字符串并将它们插入到矩阵中。每行一个字。

FILE *fp = fopen("zadanie4.txt","r");

if( fp == NULL)
{
  perror("Error while opening the file.\n");
  exit(EXIT_FAILURE);
}


int symbol, num_of_lines = 0, len_of_string = 0, max_len = 0;
do {
    symbol = fgetc(fp);
    len_of_string++;
    if (symbol == '\n' || feof(fp)) {
        num_of_lines++;

        if(len_of_string > max_len){
            max_len = len_of_string;
        }
        len_of_string = 0;
    }
} while (symbol != EOF);
fclose(fp);

printf("Number of words: %d\n", num_of_lines);
printf("Longest word: %d\n", max_len);

fp = fopen("zadanie4.txt","r");
char (*arr)[num_of_lines] = calloc(num_of_lines, sizeof(char*) * max_len); 
int index = 0;

while(fscanf(fp, "%s", arr[index++]) == 1) {  
    printf("%s\n", arr[index - 1]); //first check to see what is written into array
}
close(fp);

printf("--------------------------\n");

int i;
for(i = 0; i < num_of_lines; i++){
    printf("%s\n", arr[i]); //second check
}

我找出最长字符串的大小并为字符串数 * 最长字符串分配内存。

如果最长单词为 5(+1 表示空 '\0'),输出如下所示:

Number of words: 6
Longest word: 6
AAAAA
BBBBB
CCCCC
DDDDD
EEEEE
FFFFF
--------------------------
AAAAA
BBBBB
CCCCC
DDDDD
EEEEE
FFFFF

如果我在每一行中添加另一个字符:

Number of words: 6
Longest word: 7
AAAAAa
BBBBBb
CCCCCc
DDDDDd
EEEEEe
FFFFFf
--------------------------
AAAAAaBBBBBbCCCCCcDDDDDdEEEEEeFFFFFf
BBBBBbCCCCCcDDDDDdEEEEEeFFFFFf
CCCCCcDDDDDdEEEEEeFFFFFf
DDDDDdEEEEEeFFFFFf
EEEEEeFFFFFf
FFFFFf

注意:在此示例中,每个字符串的大小都相同,但我希望它适用于各种大小。

任何人都可以帮助我如何为这个数组正确分配内存吗?

你对arr的声明和分配是错误的,不匹配。

您将 arr 声明为指向 num_of_lines 个字符数组的指针。然后你分配 max_len 个指向字符的指针。

您可以对外部数组和内部数组使用可变长度数组:

char arr[num_of_lines][max_len + 1];  // +1 for string terminator

根本不需要动态分配。

我相信您并不真正了解 calloc 的工作原理。您不能使用

将内存分配给数组的成员
char (*arr)[num_of_lines] = calloc(num_of_lines, sizeof(char*) * max_len);

calloc 的第一个参数是为数组分配的块数量,第二个参数是每个块的大小(以字节为单位)。

相反,您想像这样定义数组

char *arr[num_of_lines];

现在需要遍历每个成员并为其分配内存

for(int i = 0; i < num_of_lines; i++) {
  arr[i] = malloc(sizeof(char) * max_len);
}

或者您可以将数组定义为静态数组,因为您知道 max_len.

的大小

您看到该行为是因为在添加额外字符时覆盖了每个字符串末尾的字符串终止符(空字符 == 0)。

与其使用一个连续的内存块,不如保留一组字符串指针,并分别分配每个字符串:

char *strings[];
strings = calloc(sizeof(char*),NUMBER_OF_STRINGS);
for i = 0; i < NUMBER_OF_STRINGS; i++ {
   strings[i] = calloc(sizeof(char), MAX_STRING_LENGTH+1);
}

然后,当您想向字符串中添加一个字符时,如果新总数小于最大字符串长度,请使用 strcat:

 strcat(strings[i],"-suffix");

或者,如果它更长,您将需要重新分配存储空间:

 strings[i] = realloc(strings[i], MAX_STRING_LEN+EXTRA_BYTES+1);
 strcat(strings[i],"-suffix");