我在APUE中阅读了make_tempory_file演示,并对以下内容感到困惑:
char good_template[] = "/tmp/dirXXXXXX"; /* right way */
char *bad_template = "/tmp/dirXXXXXX"; /* wrong way*/
void make_temp(char *template);
int main()
{
char good_template[] = "/tmp/dirXXXXXX"; /* right way */
char *bad_template = "/tmp/dirXXXXXX"; /* wrong way*/
printf("trying to create first temp file...\n");
make_temp(good_template);
printf("trying to create second temp file...\n");
make_temp(bad_template);
exit(0);
}
void make_temp(char *template)
{
int fd;
struct stat sbuf;
if ((fd = mkstemp(template)) < 0)
err_sys("can’t create temp file");
printf("temp name = %s\n", template);
close(fd);
if (stat(template, &sbuf) < 0)
{
if (errno == ENOENT)
printf("file doesn’t exist\n");
else
err_sys("stat failed");
}
else
{
printf("file exists\n");
unlink(template);
}
}
说明对其进行解释:
行为上的差异来自于两个模板字符串的声明方式。对于第一个模板,名称是在堆栈上分配的,因为我们使用数组变量。但是,对于第二个名称,我们使用指针。 在这种情况下,只有指针本身的内存位于堆栈上;编译器安排将字符串存储在可执行文件的只读段中。当mkstemp函数尝试修改字符串时,会发生分段错误。
我试图理解该声明,但坚持使用stack
它是否指向箭头所指向的堆栈?
答案 0 :(得分:3)
当mkstemp函数尝试修改字符串时,发生分段错误。
原因是因为声明为char *bad_template = "/tmp/dirXXXXXX";
bad_template
的字符串已分配给字符字符串文字。
在C
中,修改字符串文字是未定义的行为
参考-C99标准的6.4.5-6部分
字符串文字是包含在零个或多个多字节字符中的序列 双引号,例如“ xyz”。宽字符串文字相同,除了以字母L开头。
如果程序尝试修改此类数组,则行为未定义。