对于我的网络课程,我们正在构建一个基于UDP协议的bittorrent客户端,这非常酷,但由于某些原因我遇到了很多C字符串问题。
我第一次收到包时,我会这样做:
if(server_data == NULL){
server_data = malloc(one_block.total_blocks*sizeof(char*));
int i;
for(i = 0; i < one_block.total_blocks; i++){
server_data[i] = malloc(sizeof(char*));
server_data[i] = "";
}
}
此处,server_data是char**
,one_block是struct
,用于保存数据包信息和有效负载。
接下来我做:
server_data[one_block.which_block] = one_block.payload;
blocks_rcv++;
if(blocks_rcv == one_block.total_blocks-1)
done = TRUE; //macro
if(done){
int i;
for(i = 0; i < one_block.total_blocks; i++){
printf("%s", server_data[i];
}
}
一切看起来都很好,但是在收到所有数据包之前,当我打印server_data的内容时,无论什么疯狂的原因,我看到每个数据包都有不同的数据。然后我设置done = TRUE并进入for循环,数组中的每个点都包含相同的字符串值。
我不知道为什么会这样,我真的想要理解从发布的开头到结尾,数组的内容如何变化,即使我通过循环的每次迭代验证它们一次一包。
答案 0 :(得分:3)
这一行是问题所在:
server_data[i] = "";
它用指向字符串文字的指针覆盖分配的指针。由于无法修改字符串文字,如果稍后复制到此指针,则会遇到未定义的行为。
如果您想确保字符串为空,请使用calloc
,将第一个字符设置为'\0'
,或使用strcpy
进行复制新字符串。
答案 1 :(得分:0)
这里有几个问题:
1)首先,server_data,如果它被声明为char **,除非你声明,否则可能是空的,也可能不是空的。我不确定你是否将它初始化为NULL。将它显式初始化为NULL是一个好主意。
2)如果您打算让数组server_data的每个项目保存一个char *(换句话说,对字符串的引用),或者对于数组本身就是一个字符串。 one_block.payload是一个字符串,还是一组指向字符串的指针?
我用一些测试值运行你的代码,我个人没有遇到任何意外值的问题......我认为问题可能在于如何设置保存有效负载数据的结构。你能告诉我们你的one_block结构吗?什么类型的变量/数组是one_block.payload?