char * str和malloc为str的内存,仍然得到SEGFAULT

时间:2017-07-26 08:38:25

标签: c arrays string char segmentation-fault

我写了一个小C程序来反转一个字符串。 尽管如此,我还是将str声明为 char * str
然后
str = (char*)malloc(20); str = "this is a test";
但是,如果我使用
,我不会得到SEGFAULT char str[20] = "this is a test"

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

void swap(char *a, char *b)
{ 
  char temp; 
  temp = *a;
  *a = *b; 
  *b = temp; 
} 

char* reverse(char *str)
{ 
  int len = strlen(str); 
  printf("len = %d \t %s\n", len, str); 
  int i = 0; 

  if (len == 0) 
    return NULL; 
  for (i=0; i<len/2; i++) 
  { 
    swap((str+i), (str+len-1-i));    
    printf("%s\n", str); 
  } 
  return str; 
} 

int main(void)
{ 
  char *str; 
  str = (char *)malloc(20); 
  str = "this is a test"; 

  printf("%s\n", str); 
  reverse(str); 
  printf("%s\n", str); 
  return 0; 
} 

我的理解是,如果我宣布,我会得到SEGFAULT char *str="This is a test"因为它将是一个恒定的字符串 所以,我想,当我来自malloc时,str将从堆中分配,堆内存将可供两个函数访问。但, 仍然会收到SEGFAULT错误。

3 个答案:

答案 0 :(得分:6)

当你这样做时

str = (char*)malloc(20);
str = "this is a test";

重新分配指针str,在分配后立即指向其他地方。

实际上,您指向一个字符串文字,这是一个只读字符的数组。尝试修改字符串文字会导致未定义的行为

简单的解决方案是使用数组。或者复制到您使用strcpy分配的内存中。

答案 1 :(得分:5)

嗯,指针(指向字符串文字)和数组之间存在差异,它们不一样。 Check the C-FAQ for arrays and pointers了解更多信息。

首先,

  str = (char*)malloc(20); 
  str = "this is a test";

导致内存泄漏,因为您正在覆盖malloc()返回的指针。这种情况,malloc()可以简单地删除,因为您没有将任何内容存储到str的内存位置指针,而是存储未命名的const char数组的基址在指针变量中。

稍后,当您尝试将指针传递给字符串文字并尝试更改内容时,您将调用undefined behavior,因为字符串文字是只读的,并且尝试更改它们会导致UB。

另一方面,使用char数组时没有看到问题,因为数组内容是可修改的。

答案 2 :(得分:1)

 str = (char*)malloc(20);
 if(NULL != str)
 memcpy(str,"this is a test",(strlen("this is a test") + 1));