C-指示字符串的指针意外地更改其值



我注意到,当在分配的malloc()的数组中编写字符串时,其值会更改。明确的是,这是复制此"错误"的代码:

#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#define N (20)
int main()
{
   char * a_p;
   a_p = malloc( N * sizeof(char));
   printf(" * 01 pointer -> %pn", a_p);
   a_p = "something";
   printf(" * 02 pointer -> %pn", a_p);
   printf("-- TEST --n");
   return 0;
}

执行时,输出为:

 * 01 pointer -> 0x1332010
 * 02 pointer -> 0x4006b9
-- TEST --

我期望具有相同的价值,因为我没有更改指针点的位置(至少不是直接)。使用free()时,这会导致问题。木头下发生了什么?我想念什么?如何以正确的方式做这些事情?

您的问题

您正在用malloc()为指针分配内存,但是您将指针变量分配给其他东西("something",具有其自己的地址),而不是填充新分配的指针。

解决方案

您应该使用strdup()函数,该函数分配内存并在分配的内存中复制字符串:

a_p = strdup("something");

strcpy()函数,该功能采用malloc()'D指针和一个字符串,以在指向内存中复制:

a_p = malloc(N * sizeof(char));
strcpy(a_p, "something");

您直接更改指针。这个语句

a_p = "something";

等于

a_p = &"something"[0];

字符串文字具有字符数组的类型。例如,字符串文字"something"具有类型char[10]

来自C标准(6.4.5字符串文字)

6在翻译阶段7中,将一个字节或值零代码附加到 每个由字符串文字产生的多重字符序列 78)然后,多型字符序列用于 初始化一系列静态存储持续时间和长度 足以包含序列。对于字符串文字, 数组元素具有类型char,并用 多重字符序列的个体字节...

在表达式阵列中使用的,极少数例外被转换为指针转换为其第一个元素。

来自C标准(6.3.2.1 lvalues,阵列和功能指定器)

3,除非是操作员的操作数或Unary&amp; 运算符,或者是用于初始化数组的字符串 具有"类型的数组"类型的表达式转换为 用类型的"键入指针"的表达式指向初始 数组对象的元素,不是lvalue。如果数组对象 有寄存器存储类,行为不确定。

所以在此语句之后

a_p = "something";

指针指向静态存储持续时间的字符串文字的第一个字符。

我认为你是说

strcpy( a_p, "something" );

那就是您想在动态分配的内存中复制字符串字面。

考虑到即使您还可以编写以下代码

char *p1 = "string";
char *p2 = "string";

那么,p1不必等于p2,因为根据编译器选项,编译器可以将这两个相同的字符串文字放在不同的内存范围内。

所以if语句

if ( p1 == p2 )

可以产生 truefalse。将其分配给a_p时的第一个元素。该地址正在打印。

并且由于您不保留分配的内存的地址,因此内存泄漏。

您也不能在free中使用它,这给出了足够的提示,即不会动态分配它。从标准

免费功能导致PTR指向的空间为 被交易,也就是说可以进一步分配。如果ptr是 无效指针,没有任何动作。否则,如果参数不 匹配由内存管理功能返回的指针或 如果通过 freerealloc的呼叫来处理该空间,则 行为不确定。

很好,这说明了为什么在尝试free内存时遇到问题的原因。

再次具有复制之类的东西,您需要使用strcpystrncpystrdup(符合POSIX)。

有关更多信息,请检查此链接。Standard说,它明确地将其视为翻译步骤中的数组。

尤其是此部分 - (衰减指针是char*类型)

对于字符串文字,数组元素具有类型 char,并用多键的个体字节初始化 字符序列。

字符串文字"something"代表一个无效的字符系列,这些字符生存在某个只读区域中(如果您在gnu/linux系统上构建/链接/运行,则很可能.text)。

最初,a_p指向malloc在其中分配缓冲区的内存区域中的某个地方。您可以自由写入a_p点,free() IT等的位置。执行分配a_p = "something";时,您不是在将字符写入a_p点的位置,而是将该指针更改为指向该字符串的开始。现在,您要指向malloc并未分配的(仅读取)内存,因此其相应的free函数无法做任何有意义的事情。

使用strcpy(或为安全而更好,strncpy)将字符复制到目的地,a_p

相关内容

  • 没有找到相关文章

最新更新