如何正确初始化字符串

时间:2011-07-26 19:34:17

标签: c string function

我如何为以下函数定义以下字符串?

截至目前,我收到警告:

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;
      }
}

6 个答案:

答案 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)

如果你真的想要初始化 char *,你可以写一下:

const char *stringaling = "fun";

这是some reference

答案 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); 是基本类型(Tintcharfloat等,而struct ...是要分配的类型T的元素的数量。由于表达式N的类型为*pT == sizeof *p;如果您更改了sizeof(T)的类型,则无需在p调用本身中复制该更改。

第二个问题:

malloc

同样,有几个问题在起作用。首先,您无法使用*stringaling = "fun"; 运算符分配字符串值。字符串文字是数组表达式,并且在大多数上下文中,数组表达式的类型从“N元素数组T”隐式转换(“衰减”)到“指向T的指针”。您可以简单地将指针指向字符串中的第一个字符,而不是复制字符串文字的内容。

除了您在作业中取消引用=之外,哪个“有用”(见下文);表达式stringaling的类型是*stringalingconst char(在我上面指出的更改后),这与类型char的赋值不兼容。如果删除取消引用运算符并写入

char *

你修复了编译时错误,但现在又出现了另一个问题;如上所述,您尚未将字符串文字“fun”的内容复制到您使用stringaling = "fun"; 分配的内存块中;相反,您只需将字符串文字的地址复制到变量malloc即可。通过这样做,您将丢失对动态分配的块的跟踪,从而导致内存泄漏。

为了将字符串内容从一个地方复制到另一个地方,您必须使用像stringalingstrcpystrncpy这样的库函数,像这样:

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;这将防止您意外修改字符串文字。