我有一个问题,即将值赋给字符串数组,这是我的struct中的一个字段。在这种情况下,我也使用了这个结构的数组。当我在没有for循环的情况下分配值时,一切正常。但问题出现在for循环中。我打印了所有作业,他们没事。但问题实际上是,每个赋值实际上都会重写该字段的所有结构中的所有数组位置。
struct ship
{
int length;
char *fields[4];
};
struct ship shipPositions[6];
for(int h=0; h < length; h++) //goes from 0 to 3 for first two values
{
char c = getCharFromInt(begin + h); //my function which works fine; begin = 2;
char coord[3] = "$";
append(coord, c); // also works fine
append(coord,ships[i][1]);
shipPositions[i].fields[h] = coord;
printf("shipPositions[%d].fields[%d] = %s\n", i,h,shipPositions[i].fields[h]);
}
printf("Position: %s\n",shipPositions[0].fields[0]);
printf("Position: %s\n",shipPositions[0].fields[1]);
/* it prints assignments and then on the first two values after for loop
shipPositions[0].fields[0] = $C2
shipPositions[0].fields[1] = $D2
shipPositions[0].fields[2] = $E2
shipPositions[1].fields[0] = $F0
shipPositions[1].fields[1] = $G0
shipPositions[1].fields[2] = $H0
shipPositions[5].fields[0] = $H8
shipPositions[5].fields[1] = $I8
Position: $I8
Position: $I8
*/
当我模拟前两个for循环的情况时,一切都很好:
char c1 = getCharFromInt(2 + 0);
char coord1[3] = "$";
append(coord1, c1);
append(coord1,ships[0][1]);
shipPositions[0].fields[0] = coord1;
printf("shipPositions[%d].fields[%d] = %s\n", 0,0,shipPositions[0].fields[0]);
char c2 = getCharFromInt(2 + 1);
char coord2[3] = "$";
append(coord2, c2);
append(coord2,ships[0][1]);
shipPositions[0].fields[1] = coord2;
printf("shipPositions[%d].fields[%d] = %s\n", 0,1,shipPositions[0].fields[1]);
printf("Position: %s\n",shipPositions[0].fields[0]);
printf("Position: %s\n",shipPositions[0].fields[1]);
/*
shipPositions[0].fields[0] = $C2
shipPositions[0].fields[1] = $D2
Position: $C2
Position: $D2
*/
答案 0 :(得分:0)
您的代码存在2个问题。
首先,当您声明char coord[3]
时,您将创建一个长度为2个字符的字符串,因为您还需要包含NUL字符来终止字符串。但是你要在其中存储3个字符,因此你需要将其声明为char coord[4]
。
您没有提供append
的代码,但是如果它没有为您执行此操作,您需要记住分配NUL字符,即coord[3]='\0'
其次,coord
仅作为循环的每次迭代的变量存在,但它占用的内存仍将保留。将coord
分配给shipPositions[i].fields[h]
时,您指定的是指向内存的指针,而不是字符串的实际内容。当循环的迭代结束时,coord
不再存在,并且您的代码可以使用它为其他事物占用的内存(如下一个coord
实例)覆盖您希望在{{中找到的值1}}。
您应该将shipPositions[i].fields[h]
声明为fields
之类的数组数组,然后当您想隐藏char fields[4][4]
的内容时,您将使用coord
即{{1} }}。这样你就“拥有”你存储值的内存,并且在strcpy
不再存在时不会被覆盖。