尝试连接二维数组的元素时出现分段错误

Posted

技术标签:

【中文标题】尝试连接二维数组的元素时出现分段错误【英文标题】:Segmentation fault when trying to concatenate an element of a 2d array 【发布时间】:2022-01-21 15:14:02 【问题描述】:

我想使用strcat() 来连接字符串数组的元素。我试过了:

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

int main() 
    char **str = malloc(sizeof(char *) * 3);

    for (int i = 0; i < 3; i++) 
        str[i] = malloc(sizeof(char) * 8);
    

    str[0] = "foo";
    str[1] = "bar";

    strcat(str[0], "H");

    for (int i = 0; i < 3; i++) 
        printf("%s\n", str[i]);
    

    free(str);

    return 0;

我得到了错误:

Segmentation fault (core dumped)

我应该怎么做才能让它正确?

【问题讨论】:

str[0] = "foo"; str[1] = "bar"; 覆盖了内存分配指针,因此您尝试连接到字符串文字:所以是段错误。使用strcpy() 复制字符串。 请注意:您 free str 但不是这三个指针各自指向的 8 字节内存。鉴于这是主要的并且它是少量内存,这可能不是一个实际问题,但是在内存管理方面养成良好的习惯是件好事。 printf("%s\n", str[2]); 将是未定义的行为,因为分配的内存不包含字符串。 或者添加到@WeatherVane 的建议中,您可能希望使用strncpy确保您没有缓冲区溢出。同样,这里不是实际问题,而是良好的习惯...... 请注意,严格来说这不是“二维数组”,而是“锯齿状数组”或“数组数组”。 【参考方案1】:

对于初学者来说,程序有内存泄漏。最初分配了内存,其地址存储在指针 str[i]

for (int i = 0; i < 3; i++) 
    str[i] = malloc(sizeof(char) * 8);

然后指针 str[0] 和 str[1] 被字符​​串文字的地址重新分配。

str[0] = "foo";
str[1] = "bar";

因此,您可能无法通过此语句更改字符串文字

strcat(str[0], "H");

因为这会调用未定义的行为

你必须写

strcpy( str[0], "foo" );
strcpy( str[1], "bar" );

还有这个循环

for (int i = 0; i < 3; i++) 
    printf("%s\n", str[i]);

还会调用未定义的行为,因为元素 str[2] 未由字符串初始化。

您需要更改条件或循环(如i &lt; 2)或初始化元素 str[2]。

你需要释放所有分配的内存,比如

for (int i = 0; i < 3; i++) 
    free( str[i] );


free( str );

【讨论】:

以上是关于尝试连接二维数组的元素时出现分段错误的主要内容,如果未能解决你的问题,请参考以下文章

Swift:填充二维数组时出现索引超出范围错误

将指向数组的指针传递给函数时出现分段错误(C++)

初始化数组时出现段错误

C - 将结构写入二维数组会导致分段错误

尝试访问二维向量元素时出现段错误

尝试声明大数组时出现分段错误和核心转储[重复]