使用malloc的字符串进行C分段错误

时间:2017-11-26 02:14:10

标签: c segmentation-fault printf strcpy

基本上,我的代码中有一个链表的结构,

struct node{
  char* val;
  struct node *next;
};

然后我尝试做一些事情......

...
addr = malloc(sizeof(struct node));
addr->val = malloc(72);
addr->val = "";
snprintf(addr->val, 1000, "%s", ident);
...

... 这给了我snprintf的分段错误。 Valgrind说以下

Process terminating with default action of signal 11 (SIGSEGV)
==10724==  Bad permissions for mapped region at address 0x40566B
==10724==    at 0x4EB0A32: vsnprintf (vsnprintf.c:112)
==10724==    by 0x4E8F931: snprintf (snprintf.c:33)
==10724==    by 0x4016CC: id (Analyzer.c:267)
...

对C而言,我相当新,但我认为在char *上调用malloc应该使它有效,特别是因为我可以初始化和打印它,所以我不明白为什么snprintf会不会#39;工作。 我也让我的程序打印出两个变量的地址,valgrind抱怨的地址确实来自addr-> val。

我也尝试过使用strcpy而不是snprintf,但结果相同。

感谢。

2 个答案:

答案 0 :(得分:2)

addr->val = malloc(72);

此行动态分配72个字节,并将该内存区域的地址分配给addr->val

addr->val = "";

然后将addr->val设置为指向字符串常量的地址,丢弃先前包含的malloced内存区域的地址,从而导致内存泄漏。

当您尝试使用snprintf时,您尝试写入字符串文字。由于这些通常存储在内存的只读部分中,因此尝试这样做会导致核心转储。

不需要addr->val = "";。它抛弃了分配的内存;它没有将分配的内存设置为空字符串,这可能是你认为它会做的。即使它确实如此,但它仍然无用,因为snprintf将覆盖可能存在的任何内容。

答案 1 :(得分:0)

代码

var a = Promise.resolve('a');
var b = Promise.resolve('b')
var c = Promise.reject('errc');

async function test(){
const t = await Promise.all([a, b, c].map(p => p.catch(e => e)));
console.log(t);
}

test();

用“”覆盖['a,'b','errc'] 指针,静态区域的地址,由1个字符组成(值为0)。删除此行。

addr->val = malloc(72);
addr->val = "";             <====

当你只分配了72个字符时,接受1000的长度。

val

更好。