我如何为以下函数定义以下字符串?
截至目前,我收到警告:
C4047: '=' : 'const char' differs in levels of indirection from 'char [4]'
和错误:
C2166: l-value specifies const object.
以下代码的第三行:
uint8_t *buffer= (uint8_t *) malloc(sizeof(uint32_t));
const char *stringaling= (const char *) malloc(sizeof(uint32_t));
*stringaling = "fun";
newval = protobuf_writeString (buffer, stringaling);
uint32_t protobuf_writeString(uint8_t *out,const char * str)
{
if (str == NULL)
{
out[0] = 0;
return 1;
}
else
{
size_t len = strlen (str);
size_t rv = uint32_pack (len, out);
memcpy (out + rv, str, len);
return rv + len;
}
}
答案 0 :(得分:4)
const char *stringaling= (const char *) malloc(sizeof(uint32_t));
*stringaling = "fun";
这不是有效的代码。您正在尝试分配一个const变量,这是非法的。然后,您尝试为角色分配一个字符数组。最后,即使你有一个大小合适的非const字符数组,你仍然无法分配数组,因为它们不是一等值。
答案 1 :(得分:2)
尝试使用
char *stringaling = malloc(sizeof(uint32_t));
strcpy(stringaling, "fun");
...相反,看看是否效果不佳。但请注意,(至少通常情况下)sizeof(uint32_t)
恰好是保持“有趣”的正确尺寸,这是非常偶然的。你通常不想这样做。
或者,您可能需要:
char const *stringaling = "fun";
或:
char stringaling[] = "fun";
你所拥有的作业不会起作用 - C只有非常对语言中内置字符串的最小支持;大多数操作(包括复制字符串)通常通过strcpy
等库函数完成。
答案 2 :(得分:2)
"fun"
是一个字符串文字,基本上是const char *
。
stringaling
也是const char *
,因此您的第三行正在尝试将const char *
分配给const char
,这不会飞。{/ p>
如果它是一个常量字符串,你可以这样做:
const char *stringaling = "fun";
如果输入字符串是动态的,则可以执行以下操作:
char *stringaling= (char *) malloc(strlen(inputString)+1);
strcpy(stringaling, inputString);
显然,如果你使用malloc,你需要释放它,或者感受到内存泄漏的愤怒。
答案 3 :(得分:1)
答案 4 :(得分:0)
没有你可以使用的所有东西:
newval = protobuf_writeString (buffer, "fun" );
答案 5 :(得分:0)
第一个问题:
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或者没有{{1}的原型,则强制转换将禁止有用的诊断消息} 在适用范围。从1989年标准开始,malloc
返回malloc
,可以将其分配给任何其他对象指针类型而无需强制转换。在C ++中不是这样,所以在那里需要强制转换,但是如果你正在编写C ++,那么你应该使用void *
而不是new
。
因此,将该行更改为
malloc
其中LEN是您要分配的字符数。
char *stringaling = malloc(LEN); // or malloc(LEN * sizeof *stringaling), but
// in this case that's redundant since
// sizeof (char) == 1
来电的一般表格是
malloc
其中T *p = malloc (N * sizeof *p);
是基本类型(T
,int
,char
,float
等,而struct ...
是要分配的类型T的元素的数量。由于表达式N
的类型为*p
,T
== sizeof *p
;如果您更改了sizeof(T)
的类型,则无需在p
调用本身中复制该更改。
第二个问题:
malloc
同样,有几个问题在起作用。首先,您无法使用*stringaling = "fun";
运算符分配字符串值。字符串文字是数组表达式,并且在大多数上下文中,数组表达式的类型从“N元素数组T”隐式转换(“衰减”)到“指向T的指针”。您可以简单地将指针指向字符串中的第一个字符,而不是复制字符串文字的内容。
除了您在作业中取消引用=
之外,哪个“有用”(见下文);表达式stringaling
的类型是*stringaling
(const char
(在我上面指出的更改后),这与类型char
的赋值不兼容。如果删除取消引用运算符并写入
char *
你修复了编译时错误,但现在又出现了另一个问题;如上所述,您尚未将字符串文字“fun”的内容复制到您使用stringaling = "fun";
分配的内存块中;相反,您只需将字符串文字的地址复制到变量malloc
即可。通过这样做,您将丢失对动态分配的块的跟踪,从而导致内存泄漏。
为了将字符串内容从一个地方复制到另一个地方,您必须使用像stringaling
或strcpy
或strncpy
这样的库函数,像这样:
memcpy
如果strcpy(stringaling, "fun");
不需要在堆上生存(例如,您只在单个函数中使用它并在返回之前解除分配),则可以通过将其声明为完全来避免内存管理常规数组stringaling
并使用“fun”初始化它:
char
这是在声明中初始化数组的特殊情况,而不是赋值表达式,因此char stringaling[] = "fun";
将字符串文字的内容复制到=
阵列。但是,这仅适用于数组声明。您可以稍后使用其他字符串值(最多3个字符加0终结符)修改数组,但您必须再次使用stringaling
:
strcpy
如果您不需要修改strcpy(stringaling, "one");
的内容,则可以执行
stringaling
这会将字符串文字“fun”的地址复制到变量const char *stringaling = "fun";
。因为尝试修改字符串文字的内容会调用未定义的行为,所以我们做想要在这种情况下将stringaling
声明为stringaling
;这将防止您意外修改字符串文字。