我的理解如下:
char *
指向一个字符串常量,修改它指向的数据是未定义的。但是,您可以更改指向的位置。
char[]
指的是一块内存,您可以更改其内容,但不能更改内容。
strcpy(dest, src)
将src
复制到dest
。
我的问题是,使用strcpy()
dest
是char *
已经指向某事是不正确的(因为我相信旧的{/ 1}}内容将被strcpy()
覆盖 - 这是未定义的行为)?
例如:
char *dest = malloc(5);
dest = "FIVE";
char *src = malloc(5);
src = "NEW!";
strcpy(dest, src); /* Invalid because chars at dest are getting overwritten? */
答案 0 :(得分:11)
不幸的是,你的理解并不完全正确。
char *
指向字符数据,因为那里没有const
,您可以写入指向的数据。
但是,完全可以这样做:
char *a = "hello";
它为您提供了一个只读数据的读/写指针,因为字符串文字存储在只读存储器中,但不是"考虑"语言的语法不变。
将上述内容写成:
更好const char *a = "hello";
更清楚地说明您无法修改a
所指向的数据。
此外,混合malloc()
和分配的示例是错误的。
此:
char *dest = malloc(5);
dest = "FIVE"; /* BAD CODE */
代码不好,你永远不应该这样做。它只是用一个指向字符串dest
的指针覆盖"FIVE"
返回的指针,该字符串作为字符串文字存在于(再次,只读)内存中。
使用字符串数据初始化新分配的内存的正确方法是使用strcpy()
:
char *dest = malloc(5);
if(dest != NULL)
strcpy(dest, "five");
请注意,检查malloc()
的返回值是个好主意。
对同一个内存进行多次写入没有问题,这是C语言中的一个非常基本的想法;变量代表记忆,并且可以通过"写在"来为不同的时间赋予不同的值。
简单的事情:
int a = 2;
printf("a=%d\n", a);
a = 4;
printf("a=%d\n", a);
演示了这一点,当然它也适用于字符串,因为它们只是内存块。
您可以扩展以上基于malloc()
的示例:
char *dest = malloc(5);
if(dest != NULL)
{
strcpy(dest, "five");
printf("dest='%s'\n", dest);
strcpy(dest, "four");
printf("dest='%s'\n", dest);
strcpy(dest, "one");
printf("dest='%s'\n", dest);
}
它会打印出来:
dest='five'
dest='four'
dest='one'
答案 1 :(得分:3)
我的理解如下:
char *
指向一个字符串常量,修改它指向的数据是未定义的。但是,您可以更改指向的位置。
这里你指的是像
这样的表达式char * string = "mystring";
你是对的,string[1]='r';
未定义。但这不是因为char *
,而是因为字符串文字涉及到它被放入只读内存的方式。
将此与
进行比较char string[] = "mystring";
我在RAM中定义了一个数组,其中放入了所述字符串。这里允许string[1] = 'r';
,因为我们处于正常的数据存储器中。
这似乎支持你的假设,但请考虑一下:
char string[] = "mystring";
char * string2 = string;
此处string2[1] = 'r';
有效,因为它指向写作正常的位置。
char[] refers to a block of memory that you can change its contents but not what it refers to.
是的,因为名称只是变量的名称而不是指针。
strcpy(dest, src) copies src into dest.
右。
我的问题是,在dest为a时使用strcpy()是不正确的 char *已经指向某事(因为我相信旧的 内容将被strcpy()覆盖 - 这是未定义的 行为)?
这取决于你的意思"已经指向了什么" ...
例如:
char *dest = malloc(5); dest = "FIVE"; char *src = malloc(5); src = "NEW!"; strcpy(dest, src); /* Invalid because chars at dest are getting
覆盖? * /
在这里你再次混淆了几件事。
首先,你dest
指向一个全新的记忆块。之后,你可以指向其他你无法写入的地方,并且内存块丢失(内存泄漏)。
src
也是如此。
所以strcpy()
失败了。
你可以做到
char *dest = malloc(5);
char *src = "NEW!";
strcpy(dest, src);
此处dest
指向可写地点,src
指向有用数据。
答案 2 :(得分:2)
快速分析:
char *dest = malloc(5);
// 'dest' is set to point to a piece of allocated memory
// (typically located in the heap)
dest = "FIVE";
// 'dest' is set to point to a constant string
// (typically located in the code-section or in the data-section)
您要分配变量dest
两次,所以很明显,第一项任务没有意义。
就像写作:
int i = 5;
i = 6;
除此之外,你“丢失”了已分配内存的地址,因此以后你将无法释放它。
答案 3 :(得分:1)
char *是指向内存地址的指针,因此您可以修改该地址中包含的信息。
char *和char []之间的区别在于char []不是动态的,你不能改变它的大小。此外,char *指向堆中的地址,而char []存储在程序的堆栈中。
你可以将strcpy与指针和数组一起使用,它可以工作,因为两者的数据都可以被覆盖。