【问题标题】:Strncpy issue with Double Pointer Char Array双指针字符数组的 Strncpy 问题
【发布时间】:2021-02-19 00:17:33
【问题描述】:

我似乎无法弄清楚下面的代码有什么问题:

我有一个双指针 char 数组,声明并初始化如下:

unsigned char **buffer = (unsigned char**) malloc (num * sizeof(char*));
for ( i = 0; i < num; i++ )
{
    buffer[i] = (unsigned char*) calloc(PACKETSIZE, sizeof(char));
}

然后我试图将一个字符串复制到 char* 数组之一的中间部分,但它似乎不起作用。我不确定我的错误是内存分配还是我尝试复制时。我知道来源char* 有内容。

我要复制的代码(Header 是一个结构,我想在 Header 的内存地址之后写入数组为buffer[i],所以我正在做一些指针运算)。

 strncpy ((unsigned char *)(buffer[i]+sizeof(Header)), buffer2, bytes_to_copy);

代码运行后,buffer[i] 保持为空。

这是 Header 结构的示例:

typedef struct Head
{
    unsigned int x; 
    unsigned int y; 
} Header ;

【问题讨论】:

  • 一般提示:strncpy 不是更安全的strcpy 版本。仔细阅读文档。
  • 那么PACKETSIZE和sizeof(Header)是什么关系呢?这闻起来像是一个普通的越界访问。分几步执行这些操作,将buffer[i]+sizeof(Header) 存储在 tmp 变量中并在调试器中观察它。是否有意义?另外,总是怀疑危险的strncpy 函数,在这种情况下它实际上是否终止了字符串?如果可能,请改用更安全的strcpymemcpy
  • 另外......如果你调用buffer[i],它全为零。如果您随后写信给buffer[i] + whatever,那么buffer[i] 仍将包含零。那么“空”是什么意思?根据您的程序设计,字符串 buffer[i] 的开头有一个空终止符。
  • 所以我的问题似乎是你和阿德里安在下面的回答的结合。对于我的 strncpy,我最初忘记添加 Null 字符来终止我的缓冲区。但是,在我使用 strcpy 修复它之后,当我认为它仍然无法正常工作时,我的调试器语句仍然没有输出任何内容,但这是由于我的标头具有小的 unsigned int 值,当一个字节中有 0 时,它会起作用就像我的调试语句的空字符一样,所以数据包看起来是空的,但实际上不是。谢谢大家!
  • 非常感谢大家的帮助!整个晚上都被困在这个问题上。

标签: c strcpy pointer-arithmetic double-pointer


【解决方案1】:

您的分配线:

    buffer[i] = (unsigned char*) calloc(PACKETSIZE, sizeof(char));

会将buffer[i]所有元素设置为零。

然后,你的复制行:

    strncpy ((unsigned char *)(buffer[i]+sizeof(Header)), buffer2, bytes_to_copy);

设置在第一个sizeof(Header)元素之后出现的buffer[i]数据。

因此,那些第一个 sizeof(Header) 元素将为零。因此,任何使用strxxx 函数显示该缓冲区的尝试都将假定字符串为空(第一个字节为零)。

【讨论】:

  • 对不起,我忘了说我已经为标题设置了值。
  • @TimZ 但是你把它们设置为是什么?很有可能,如果标头结构的第一个 int 类似于 7,那么它的第一个 byte仍然 为零。如果您想使用字符串函数来计算或打印数据,您需要将buffer[i]+sizeof(header) 传递给这些函数中的每一个
  • 这是真的!!我认为这就是我的调试器 (printf) 无法工作的原因,因为我正在尝试打印 %s。有没有办法让我打印整个 char 数组的整个长度,而不管 0 是多少?
  • @TimZ 我的建议是不要将字符串存储用于非字符串数据的数据。也许制作一个struct,其中包含您的标题的xy 元素加上 一个char* 数据指针?
  • 不幸的是,这是不可能的:(我正在尝试通过套接字调用发送数据包。但无论如何,我认为我的问题已经解决,谢谢!我还想出输出正确的数据部分字符串,我可以再次使用指针算术。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-28
  • 1970-01-01
相关资源
最近更新 更多