【问题标题】:Assigning value to char pointer directly after malloc is causing Segmentation error在 malloc 之后直接为 char 指针赋值会导致分段错误
【发布时间】:2020-05-12 13:17:36
【问题描述】:

我正在尝试对 char 数组执行简单的字符串操作 (strcat)。我尝试了两种方法。

在第一种情况下,我将内存分配给 char*,然后通过 scanf() 分配值。 这种方法效果很好。

void fun1(char** s1) {
    char temp[15] = "&Superman";
    printf("inside fun1 %s %s\n",(*s1),temp);
    strcat((*s1),temp);
}

int main()
{
    char *str;
    str = malloc(sizeof(char)*15);
    scanf("%s",str);
    fun1(&str);
    printf("1st string %s\n",str);

    return 0;
}

这个案例的 O/p 符合预期

Batman
inside fun1 Batman &Superman
1st string Batman&Superman

在第二种方法中,我直接在 main() 中为 str 赋值,而不使用 scanf()。

void fun1(char** s1) {
    char temp[15] = "&Superman";
    printf("inside fun1 %s %s\n",(*s1),temp);
    strcat((*s1),temp);
}

int main()
{
    char *str;
    str = malloc(sizeof(char)*15);
    str = "Batman";
    fun1(&str);
    printf("1st string %s\n",str);

    return 0;
}

在这种情况下,我在执行 strcat 时在 fun1() 中遇到分段错误。

inside fun1 Batman &Superman
Segmentation fault (core dumped)

来自OnlineGDB的GDB o/p

(gdb) r                                                                           
Starting program: /home/a.out                                                     
inside fun1 Batman &Superman                                                      

Program received signal SIGSEGV, Segmentation fault.                              
__strcat_sse2_unaligned ()                                                        
    at ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:666                    
666     ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S: No such file or direc
tory.                                                                             
(gdb) bt                                                                          
#0  __strcat_sse2_unaligned ()                                                    
    at ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:666                    
#1  0x00000000004006a3 in fun1 (s1=0x7fffffffebd8) at main.c:9                    
#2  0x00000000004006e4 in main () at main.c:17                                    
(gdb)             

我很困惑,因为字符串 "Batman" 能够在 fun1() 中打印,但它的 strcat 失败了,尽管我对这两种情况都做了同样的事情。

提前感谢您的帮助。

【问题讨论】:

  • 此外,您的第一个代码会调用未定义的行为,因为您只分配 15 个字节,而您需要 16 个字节来保存包含 nul 终止符的结果字符串。
  • 为什么要在第二个代码中分配内存?您立即丢弃地址导致内存泄漏。
  • @Gerhardh 是的,我的错。我只是在尝试一些东西。

标签: c string pointers segmentation-fault malloc


【解决方案1】:

当你这样做时

str = "Batman";`

str 不再指向 malloc 的内存。它指向字符串文字“batman”。所以你不能连接另一个字符串。

查看这一点的一种方法是添加一些简单的打印 - 尝试:

char *str;
str = malloc(sizeof(char)*15);
printf("%p\n", (void*)str);
str = "Batman";                // str now points to a different location
printf("%p\n", (void*)str);

改用strcpy

str = malloc(sizeof(char)*15);
strcpy(str, "Batman");

注意:您为“Batman”和“&Superman”的串联分配的内存太少。第一个是 6 个字符,第二个是 9 个字符,所以你需要 6+9+1 = 16 个字符。最后一个 +1 用于保存字符串终止字符,即\0。所以除了使用strcpy,还需要分配16个字符。

顺便说一句:

  • 您不需要将str 的地址传递给函数,因为函数永远不会像*s1 = ... something... 这样进行任何赋值,只需传递str

  • sizeof(char) 始终为 1,因此您无需编写它。

【讨论】:

  • 好的,我明白了。我们不能改变文字。但是您关于无需传递str 的地址的第二点,我有点困惑。 strcat 不是在修改我们的字符串吗?
  • @battyman17 是的,strcat 更改字符串 - 或其他:它更改了 指针指向的内存但它没有改变指针!因此,您不需要传递“指针地址”
  • 我们是否需要检查malloc() 返回值if (str) 来查看内存分配是否成功?以及程序返回之前的free()
  • @EsmaeelE 您应始终检查malloc 返回的值。当程序返回时,您不需要free,因为它会在程序终止时自动发生。但是,许多人认为明确调用 free 是一个好习惯
猜你喜欢
  • 2018-10-19
  • 2011-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-04
相关资源
最近更新 更多