第一个问题:
const char *stringaling= (const char *) malloc(sizeof(uint32_t));
这条线上有几个问题。
首先,您不想将stringaling 声明为const char *;您将无法修改 stringaling 指向的任何内容(IOW,*stringaling 将不可写)。这很重要,因为您想将另一个字符串的内容复制到stringaling 指向的位置。删除 const 关键字。
其次,malloc(sizeof(uint32_t)) 恰好为这个特定的字符串分配了足够的字节 (4),但不清楚您的意思是 分配 4 个字节。为数组分配内存时(字符串是数组),明确指出您打算分配的元素数量。
最后,转换 malloc 的结果在 C 中被认为是不好的做法。如果您忘记包含 stdlib.h 或在范围内没有 malloc 的原型,转换将抑制有用的诊断消息。从 1989 年标准开始,malloc 返回 void *,可以将其分配给任何其他对象指针类型,而无需强制转换。这在 C++ 中是不正确的,所以这里需要强制转换,但是如果你正在编写 C++,你应该使用 new 而不是 malloc。
所以,把那行改为阅读
char *stringaling = malloc(LEN); // or malloc(LEN * sizeof *stringaling), but
// in this case that's redundant since
// sizeof (char) == 1
其中 LEN 是您要分配的字符数。
malloc 呼叫的一般形式是
T *p = malloc (N * sizeof *p);
其中T 是基本类型(int、char、float、struct ... 等),N 是类型的元素 的数量T 你要分配。由于表达式*p的类型是T,所以sizeof *p == sizeof(T);如果您更改了p 的类型,您不必在malloc 调用本身中复制该更改。
第二个问题:
*stringaling = "fun";
同样,有几个问题在起作用。首先,您不能使用= 运算符分配字符串值。字符串字面量是数组表达式,在大多数情况下,数组表达式的类型从“T 的 N 元素数组”隐式转换(“衰减”)到“指向 T 的指针”。您只需将指针分配给字符串中的第一个字符,而不是复制字符串文字的内容。
除了你在作业中取消引用 stringaling 之外,哪个会“工作”(见下文);表达式*stringaling 的类型是const char(在进行了我上面指出的更改后的char),这与char * 类型的赋值不兼容。如果你放弃解引用运算符并写
stringaling = "fun";
您会修复编译时错误,但现在您遇到了另一个问题;如上所述,您还没有将字符串文字“fun”的内容复制到您使用malloc 分配的内存块中;相反,您只需将字符串文字的地址复制到变量stringaling。这样一来,您就会忘记动态分配的块,从而导致内存泄漏。
为了将字符串 contents 从一个地方复制到另一个地方,您必须使用像 strcpy 或 strncpy 或 memcpy 这样的库函数,如下所示:
strcpy(stringaling, "fun");
如果stringaling 不需要驻留在堆上(例如,您只在单个函数中使用它并在返回之前释放它),您可以通过将其声明为常规数组来完全避免内存管理char 并用 "fun" 对其进行初始化:
char stringaling[] = "fun";
这是在声明中初始化数组而不是赋值表达式的特殊情况,因此= 确实将字符串文字的内容复制到stringaling 数组。但是,这只适用于数组声明。您可以稍后使用其他字符串值(最多 3 个字符加上 0 终止符)修改该数组,但您必须再次使用 strcpy:
strcpy(stringaling, "one");
如果你不需要修改stringaling的内容,你可以这样做
const char *stringaling = "fun";
这会将字符串文字“fun”的地址复制到变量stringaling。并且由于尝试修改字符串文字的内容会调用未定义的行为,因此我们确实希望在这种情况下将stringaling 声明为const char *;这将防止您意外修改字符串文字。