【问题标题】:Appending to dynamically allocated array附加到动态分配的数组
【发布时间】:2011-10-25 12:51:01
【问题描述】:

我正在尝试将接收到的数据添加到需要在运行时可配置的缓冲区(我从文件或命令行读取大小)。

所以基本上我确定我的buffersize 并使用calloc 分配一个内存区域(如果它不在配置文件或命令行中,我也会设置一个总括来设置缓冲区大小 - 假设我们现在使用它)。

我只放置适用的代码行。

int buffersize=10000;
void *BuffPtr = (void *)calloc(1,buffersize * sizeof(char));

然后我有一个来自 UDP 的 recv(我已经尝试接收到 char 数组和动态分配的数组 - 两者都工作正常)

// Setup socket......

void *PktBuff = (void *)calloc(1,1000 * sizeof(char));

// Loop and receive many packets......

rcvd_bytes=recv(recv_socket, PktBuff, 1000, 0);

此时,我可以编写PktBuff 的内容,它工作正常。但我想在我的动态分配数组(上面定义的BuffPtr)中连接一些接收到的数据包。

我已经尝试过 strcat,但如果我尝试写入收到的第一个数据包,我只会得到垃圾,而不是收到另一个数据包。

strcat(BuffPtr, PktBuff);

我做错了什么??

提前致谢。

【问题讨论】:

  • strcat 依赖 '\0' 作为字符串终止符。尝试在 strcat 之后添加它。
  • 你在调用calloc 错误:第一个参数是要分配的项目数(第一个代码块中的buffersize),第二个参数是每个项目的大小.应该是calloc(buffersize, sizeof(char))
  • @BigMike errr no... 假设 BuffPtr 仅由非 \0 字节组成。

标签: c


【解决方案1】:

您的数据似乎不是以 0 结尾的字符串,您可能想改用 memmove

【讨论】:

  • 也许它可以读取 999 字节到 PktBuff?由于 calloc 零初始化内存。
  • 或者分配1001个字节。也就是说,如果我们假设,数据中没有零。
  • 迈克尔,我试过 memove 它适用于第一个实例,然后我得到第二个和后续数据包的垃圾。
  • 只是要小心你移动的东西,并确保你有足够的空间来移动东西。
  • 好的,我有足够的空间,但仍然是同样的问题 - 我的 recv 循环第一次连接,但第二次,只有一行 'garbage' 被添加到我动态的末尾分配的数组 - 或者看起来 - recv 缓冲区包含正确的信息,但 memmove 或 memcpy 只会添加垃圾。有什么想法吗?
【解决方案2】:

几点和观察:

  1. 不要在 C 中强制转换 malloc() 的返回值。
  2. 表达式sizeof (char) 是一种冗长的写法1,乘以它很少能提供信息。
  3. 确保所有数据都以 0 结尾(字符串),否则您不能使用字符串函数,因为这是它们所需要的。
  4. 您可能应该只使用一个额外的 size_t 计数器来跟踪 BuffPtr 中的字节数,并使用它和 memcpy() 进行追加。

【讨论】:

  • 谢谢,我确实有一个 BuffPtr 中总字节数的计数器,并且按照 Michael 的建议,我使用了 memove,它稍微改善了一些情况。我一定错过了数据包上的终止字符串之类的东西??会检查的。
【解决方案3】:

好的,您的代码中存在一些问题 strcat 不是附加二进制数据的正确方法。这是一个半稳健的实现。我没有检查它的语法错误,只是把它打出来,请作为例子学习它,并根据你的代码进行调整。

/* total number of bytes you are willing to receive in single a single receive */ 
#define MAX_RECV_BUFFER 1000

/* total number of bytes you are willing to store in memory */
#define MAXBYTES MAX_RECV_BUFFER*1000

int append_bytes() {
    char rcvbuf[MAX_RECV_BUFFER]; /* buffer where things are received */
    void *buf = NULL; /* buffer where bytes are collected */
    size_t rcvlen; /* length of data received */
    size_t buflen = 0; /* total bytes */

    while(1) {
         void *p;
         rcvlen = recv(recv_socket, rcvbuf, MAX_RECV_BUFFER, 0);
         if ( rcvlen < 0 ) { manage_error(); }
         if ( rcvlen == 0 ) 
                 break;
         if ( buflen + rcvlen > MAXBYTES) 
                 break;
         p = realloc(buf, buflen+recvlen);
         if ( !p ) { manage_memory_error(); }
         buf = p; /* we have enough space */
         memcpy(buf+buflen, rcvbuf, recvlen); /* append new content to end of buffer */
         buflen+=recvlen; /* add length to buflen */
    }      
}

【讨论】:

  • 谢谢,但编译器不喜欢 memcpy。我已经完全按照你的方式声明了事情(删除了我以前的 calloc),并在 memcpy 中得到一个引用 buf+buflen 参数的编译器错误:表达式必须是指向完整对象类型的指针??????
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-06
  • 2014-06-19
  • 2011-03-25
  • 2019-09-04
  • 2018-06-10
  • 1970-01-01
  • 2020-09-13
相关资源
最近更新 更多