我的理解如下:
-
char *
指向一个字符串常量,修改它所指向的数据是未定义的。但是,您可以更改它指向的位置。 -
char[]
是指可以更改的内存块。 -
strcpy(dest, src)
复制src
到dest
。
我的问题是,使用strcpy()
与dest
作为已经指向的char *
是不正确的(因为我相信旧内容将被strcpy()
覆盖-这是未定义的行为)?
char *dest = malloc(5);
dest = "FIVE";
char *src = malloc(5);
src = "NEW!";
strcpy(dest, src); /* Invalid because chars at dest are getting overwritten? */
char *
指向字符数据,因为没有const
在那里,你可以写被指向的数据。
然而,这样做是完全可能的:
char *a = "hello";
给你一个只读数据的读/写指针,因为字符串字面值存储在只读内存中,但不被语言的语法"认为"是常量。
最好这样写:
const char *a = "hello";
说明不能修改a
所指向的数据。
另外,你的例子混合malloc()
和分配是错误的。
:
char *dest = malloc(5);
dest = "FIVE"; /* BAD CODE */
是不好的代码,你不应该这样做。它只是用一个指向字符串"FIVE"
的指针覆盖dest
返回的指针,该指针存在于(同样是只读的)内存中的某个地方,作为字符串字面值。
用字符串数据初始化新分配的内存的正确方法是使用strcpy()
:
char *dest = malloc(5);
if(dest != NULL)
strcpy(dest, "five");
请注意,检查malloc()
的返回值是一个好主意。
对同一内存进行多次写操作是没有问题的,这是C语言中一个非常基本的思想;变量代表内存,可以通过"重写"在不同的时间赋予不同的值。
就像:
int a = 2;
printf("a=%dn", a);
a = 4;
printf("a=%dn", 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'
我的理解如下:
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.
.
我的问题是,使用strcpy()与dest是a是不正确的已经指向某些东西的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
指向有用数据
快速分析:
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;
最重要的是,您"丢失"了已分配内存的地址,因此您将无法在以后释放它。
char*是指向内存地址的指针,因此可以修改该地址中包含的信息。
char*和char[]的区别在于char[]不是动态的,你不能改变它的大小。此外,char *指向堆中的地址,而char[]存储在程序的堆栈中。
你可以对指针和数组使用strcpy,因为两者的数据都可以被覆盖。