0

我有一个包含指针数组的结构。我想以字符串格式插入数组数字,即“1”、“2”等。

但是,使用 sprintf 或 strncpy 有什么区别吗?

我的代码有什么大错误吗?我知道我必须免费拨打电话,我将在我的代码的另一部分中这样做。

非常感谢您的任何建议!

struct port_t
{
    char *collect_digits[100];

}ports[20];

/** store all the string digits in the array for the port number specified */
static void g_store_digit(char *digit, unsigned int port)
{
    static int marker = 0;
    /* allocate memory */
    ports[port].collect_digits[marker] = (char*) malloc(sizeof(digit)); /* sizeof includes 0 terminator */
    // sprintf(ports[port].collect_digits[marker++], "%s", digit);
    strncpy(ports[port].collect_digits[marker++], digit, sizeof(ports[port].collect_digits[marker]));
}
4

5 回答 5

3

是的,您的代码有一些问题。

  • 在 C 中,不要强制转换malloc(). 它不是必需的,并且可以隐藏错误。
  • 您根据指针的大小分配空间,而不是您要存储的大小。
  • 复制也是一样。
  • 目前还不清楚静态的marker作用,以及它周围的逻辑是否真的正确。是port要更改的插槽,还是由静态变量控制?

您想在数组中的每个插槽中仅存储一位数字还是多位数字?

给定声明,该函数的外观如下:

/* Initialize the given port position to hold the given number, as a decimal string. */
static void g_store_digit(struct port_t *ports, unsigned int port, unsigned int number)
{
  char tmp[32];

  snprintf(tmp, sizeof tmp, "%u", number);
  ports[port].collect_digits = strdup(tmp);
}
于 2009-03-31T06:34:31.997 回答
2
strncpy(ports[port].collect_digits[marker++], digit, sizeof(ports[port].collect_digits[marker]));

这是不正确的。

您已为 collect_digits 分配了一定数量的内存。

您将 char *digits 复制到该内存中。

您应该复制的长度是 strlen(digits)。您实际复制的是 sizeof(ports[port].collect_digits[marker]),它将为您提供单个 char * 的长度。

您不能使用 sizeof() 来查找已分配内存的长度。此外,除非您先验地知道数字与您分配的内存长度相同,否则即使 sizeof() 确实告诉您分配的内存的长度,您也会复制错误的字节数(太多;您只需要复制数字的长度)。

此外,即使两个长度始终相同,以这种方式获取长度也没有表现力;它误导了读者。

另请注意,如果指定的复制长度大于源字符串的长度,则 strncpy() 将用尾随 NULL 填充。因此,如果digits分配的内存的长度,您将有一个非终止字符串。

sprintf() 行在功能上是正确的,但是对于您正在做的事情, strcpy() (与 strncpy() 相对)是,从我所看到和知道的代码来看,正确的选择。

不得不说,我不知道你想做什么,但是代码感觉很别扭。

于 2009-03-31T06:38:47.247 回答
1

第一件事:为什么要有一个指针数组?你期望一个端口对象有多个字符串吗?您可能只需要一个普通数组或一个指针(因为您malloc稍后会 -ing)。

struct port_t
{
    char *collect_digits;
}ports[20];

您需要传递字符串的地址,否则,malloc 会作用于本地副本,您将永远无法取回您支付的费用。

static void g_store_digit(char **digit, unsigned int port);

最后,它sizeof适用于指针上下文并且没有给你正确的大小。

于 2009-03-31T06:33:00.130 回答
1

而不是使用malloc()and strncpy(),而只是使用strdup()- 它分配足够的缓冲区来保存内容并将内容复制到新字符串中,所有这些都是一次性的。

所以你根本不需要g_store_digit()- 只需使用strdup(), 并保持marker在调用者的级别。

于 2009-03-31T06:38:46.607 回答
1

原代码的另一个问题:语句

strncpy(ports[port].collect_digits[marker++], digit, sizeof(ports[port].collect_digits[marker]));

引用markermarker++相同的表达式。在这种情况下,++ 的评估顺序是未定义的——第二个引用marker可以在执行增量之前或之后评估。

于 2009-03-31T14:42:09.017 回答