C memcpy的行为不符合预期

C memcpy的行为不符合预期,c,pointers,memcpy,C,Pointers,Memcpy,这个问题与 借用那里的代码,我有这样的东西(感谢luser droog提供了一个很好的示例代码): 这可能不会直接跑出去,但它说明了一些类似于我正在跑的东西。基本上,每次循环迭代后,都需要将strv的内容存储在strv中,并且strv会根据用户输入随时间而变化 使用calloc和memcpy应该使strvv在循环的每次迭代中保持strv的副本,而不依赖于strv中的值。然而,当我打印出strv的内容时,它为每个条目打印出相同的字符串,这意味着当前的方法仍然在移动指针,而不是在每个strv条目中复

这个问题与

借用那里的代码,我有这样的东西(感谢luser droog提供了一个很好的示例代码):

这可能不会直接跑出去,但它说明了一些类似于我正在跑的东西。基本上,每次循环迭代后,都需要将strv的内容存储在strv中,并且strv会根据用户输入随时间而变化

使用calloc和memcpy应该使strvv在循环的每次迭代中保持strv的副本,而不依赖于strv中的值。然而,当我打印出strv的内容时,它为每个条目打印出相同的字符串,这意味着当前的方法仍然在移动指针,而不是在每个strv条目中复制strv


我根本不知道为什么会发生这种情况,也不知道如何解决。memcpy应该在字节级复制strv中的指针指向的=/。

这更接近于我之前的建议

enum { BUFSZ = 50 };
enum { STRVSZ = 40 };
enum { STRVVSZ = 20 };
char buf[BUFSZ + 1];
char *strv[STRVSZ + 1];
char **strvv[STRVVSZ + 1];

int j; // indexes strv slices in strvv
int i; // indexes strings (char *s) in strv

j = 0; // j is index into strvv

while(!feof(infile)) {

    i = 0; // i is index into strv
    while(i < STRVSZ){
        fgets(buf, BUFSZ, infile);
        if (strcmp(buf,"END")==0) break; // end of a set

        strv[i] = strdup(buf);
        strv[i+1] = NULL;
        i++;
    }  // i is count of strv

    // copy strv into strvv
    strvv[j] = calloc(i+1, sizeof *strvv[j]); // assuming i is the count of elements 
    memcpy(strvv[j], strv, (i+1) * sizeof *strvv[j]);  // i+1 to copy the NULL pointer
    j++; // index next element in strvv and a count of strvv

} // j is count of sets in strvv
enum{BUFSZ=50};
枚举{STRVSZ=40};
枚举{strvsz=20};
字符buf[BUFSZ+1];
字符*strv[STRVSZ+1];
字符**strvv[STRVVSZ+1];
int j;//在strv中索引strv切片
int i;//索引strv中的字符串(字符*s)
j=0;//j是strv的索引
而(!feof(infle)){
i=0;//i是strv的索引
而(i
感觉还是一团糟


功能。它需要更小、明确定义的功能。这里的变量都是一些更有意义的占位符

您是否看到每次迭代都会将
i
j
重置为零(0),并随后公然覆盖以前保存的数据?忘记代码,并声明以下内容。你想干什么?创建一个由动态字符串组成的网格,其中每个单元格都是char*,每行都是char*[],整个网格都是char**[]?我应该在这里承担一些责任
i
应该是添加到
strv
的最后一个条目的索引。因为
i
是零,所以零乘以任何值都是零,memcpy不会复制任何值
i
这里需要复制的元素数。@luserdroog ok。我想我现在差不多明白了。对于每个字符串的“集合”,新集合存储在伪矩阵的新行中,其中每一行实际上可以有任意数量的字符串(包括零个,但不超过STRVSZ),并以空指针结尾,以指示该行字符串列表的结尾。是这样吗?@WhozCraig是的。这就是我想解释的。我想这就是OP想要做的。一串一串的弦。Where是作为一个动态数组实现的。我没有注意到示例中的I问题,因为我在自己的代码中将其转换为正确的变量,该变量可以获得数组的大小。我可以用这个代码在strvv中输入数据,但是当我试图读取array.Hmm时,它仍然指向同一个东西。我不知道!对于每一个新的级别,它都应该完全遵循相同的模式。
memcpy
应复制
strv
中的所有指针。然后你应该重置
i=0
用下一组填充
strv
。我之所以让它们漂浮,是因为它们的位置取决于其他情况。这将变成一场噩梦!我认为是时候寻找一种更好的方法来做我想做的事情了(希望是一种不包括3D阵列的方法…),这样就不会那么复杂了。非常感谢你的帮助,从技术上来说,我不能接受这个答案,因为如果将来有人问这个问题,这实际上不是一个答案,但我会+1。明白。这种混乱是C++的全部原因!
enum { BUFSZ = 50 };
enum { STRVSZ = 40 };
enum { STRVVSZ = 20 };
char buf[BUFSZ + 1];
char *strv[STRVSZ + 1];
char **strvv[STRVVSZ + 1];

int j; // indexes strv slices in strvv
int i; // indexes strings (char *s) in strv

j = 0; // j is index into strvv

while(!feof(infile)) {

    i = 0; // i is index into strv
    while(i < STRVSZ){
        fgets(buf, BUFSZ, infile);
        if (strcmp(buf,"END")==0) break; // end of a set

        strv[i] = strdup(buf);
        strv[i+1] = NULL;
        i++;
    }  // i is count of strv

    // copy strv into strvv
    strvv[j] = calloc(i+1, sizeof *strvv[j]); // assuming i is the count of elements 
    memcpy(strvv[j], strv, (i+1) * sizeof *strvv[j]);  // i+1 to copy the NULL pointer
    j++; // index next element in strvv and a count of strvv

} // j is count of sets in strvv