C语言 Understanding char *, char[] and strcpy()



我的理解如下:

  • char *指向一个字符串常量,修改它所指向的数据是未定义的。但是,您可以更改它指向的位置。

  • char[]是指可以更改的内存块。

  • strcpy(dest, src)复制srcdest

我的问题是,使用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,因为两者的数据都可以被覆盖。

最新更新