下面的代码在运行时不会出现seg错误
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node {
char *data;
struct node *next;
};
int main(void)
{
struct node *head = malloc(sizeof(struct node));
head->data = "test";
printf("data: %s\n", head->data);
return 0;
}
当我把代码切换成so时
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node {
char *data;
struct node *next;
};
int main(void)
{
struct node *head = malloc(sizeof(struct node));
strncpy(head->data, "test", 512);
printf("data: %s\n", head->data);
return 0;
}
我收到了一个seg错误,并被迫将我的节点属性数据切换为char数据类型[512]。为什么需要这样做?我认为数组本质上是指针,所以这种行为对我来说没有意义。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node {
char data[512];
struct node *next;
};
int main(void)
{
struct node *head = malloc(sizeof(struct node));
strncpy(head->data, "test", 512);
printf("data: %s\n", head->data);
return 0;
}
我希望指针和数组都能以同样的方式被赋予字符串值。
4条答案
按热度按时间7kqas0il1#
在这份声明中
具有数组类型
char[5]
的字符串文字被隐式转换为指向其第一元素的指针,并且该指针被分配给指针head->data
。在这份声明中
你正在使用一个未初始化的指针
head->data
,并试图将整个字符串文本复制到该指针所指向的内存中,该指针具有一个不确定的值。这将调用未定义的行为。我认为数组本质上是指针,所以这种行为对我来说没有意义。
数组不是指针。在大多数情况下,数组可以隐式转换为指向其第一个元素的指针,但这并不意味着数组是指针。
考虑下面的简单演示程序。
其输出可能如下所示
flseospp2#
在第二个代码段(崩溃的代码段)中,为
node
结构体分配内存,该结构体包含指针data
,但是,该指针从未初始化,它指向某个任意内存地址(或仅指向NULL
),这意味着写入它的操作是undefined behavior,实际上可能只是segfault。为了让它指向一个有效的内存地址,你必须显式地分配它:
jdgnovmf3#
我认为数组本质上是指针,所以这种行为对我来说没有意义。
指针只是指针,它们占用的内存只是存储地址所需的内存。如果你想让指针指向动态分配的内存,你需要自己分配它。
示例:
lvmkulzt4#
我以为数组本身就是指针
数组在表达式和函数参数中可能会退化为指针,数组访问可能会被编译器重写为指针访问,但它们是不可互换的。数组名是地址,指针是地址的地址。
为什么需要这样做?
声明指针只为指针分配内存。
您可以通过两种方式初始化指针:
最初,
ptr
是不确定的,但是这改变了它所指向的内容,现在它指向一个字符串,编译器将字符串的第一个元素的地址存储在ptr
中。如果你对一个
阵列:
然后尝试改变它的值:
它不能编译,因为数组不像指针,是不可修改的左值,你不能改变它的值。
写信给它。
现在您可以使用
strcpy ()
复制到它。