正在打印的结构中我的 int** 的垃圾输出
Garbage output of my int** in a struct being printed
我从一个文件中读取整数值,通过 space 字符解析它们,然后将它们插入到一个名为 game 的结构中的 int** 中。使用 print 语句,我已经确认正确的值被放置在 int** 的正确位置,但是一旦我离开 while 循环或 return 结构,打印的值是错误的。
我的结构:
typedef struct Map_s{
char * defender;
char * attacker;
int missles;
int ** layout;
size_t capacity;
size_t size;
}map;
结构初始化:
map * newGame(){
map * game = malloc(sizeof(map));
game->layout = (int**)malloc(_DEFAULT_MAP_SIZE * sizeof(int*));
game->defender = NULL;
game->attacker = NULL;
game->missles = 0;
game->capacity = _DEFAULT_MAP_SIZE;
game->size = 0;
return game;
}
文件解析:
map * game = newGame();
char * token;
char * dup;
char * ptr;
int ret;
const char delim[2] = " ";
char * buf = NULL;
char * temp = NULL;
size_t size = _MAX_SIZE;
int lineNum = 1;
while( getline(&temp, &size, fp) > 1 ){
buf = strtok(temp, "\n");
dup = strdup(buf);
if( buf[0] != '#' ){
if( lineNum == 1){
if( game->defender == NULL ){
game->defender = dup;
}
}
else if( lineNum == 2 ){
if( game->attacker == NULL )
game->attacker = dup;
}
else if( lineNum == 3 ){
game->missles = atoi(dup);
}
else if( lineNum > 3 ){
token = strtok(dup, delim);
while( token != NULL ){
if( game->size >= game->capacity ){
game->layout = (int**)realloc(game->layout, \
game->capacity*2 * sizeof(int*));
game->capacity = game->capacity * 2;
}
ret = (int)strtol(token, &ptr, 10);
game->layout[game->size] = &ret;
game->size = game->size + 1;
token = strtok(NULL, delim);
//printf("%s ", token);
}
}**
lineNum++;
}
}
return game;
我几乎可以肯定我的代码在第二个 while 循环中的某个地方搞砸了。我正在尝试将字符串转换为整数,然后将其保存到 int** 中的正确位置。
我如何从 main 打印:
for( size_t i = 0; i < thisgame->size; i++ ){
printf("%d ", *thisgame->layout[i]);
if( i == 0)
continue;
else if( (i+1) % 10 == 0 )
printf("\n");
}
returning 结构后主函数的输出:
0 0 0 0 0 0 0 0 0 0
10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10
输出应该是什么样的(文件中有什么):
2 2 2 2 2 2 2 2 2 2
2 2 6 6 7 7 7 5 5 2
2 2 7 7 7 2 2 17 17 17 2
2 2 2 2 2 2 2 2 2 2
8 8 8 6 6 6 9 9 9 2
2 2 2 2 2 2 2 2 2 2
10 10 10 4 4 9 9 9 2
2 2 2 2 2 2 2 2 2 2
3 3 3 6 6 6 9 9 9 2
3 3 3 6 6 6 9 9 9 2
2 2 2 2 2 2 2 2 2 2
我发现了几个问题。
首先是行 **token = strtok(dup, delim);
。在此行的第一个 运行 处,token
没有有效值,因此取消引用它不是一次,而是两次,也会导致问题。我相信这应该只是 token = strtok(dup, delim);
这将导致 if 块中的 while 循环的第一次迭代到 return 错误值(至少所有这些 0 似乎符合这个猜测)。
其次是 D Go 指出的,因为您给出了 ret
的地址(该地址不会改变),因此 game->layout
的每个元素都具有相同的地址,并且因此查看相同的 int (适合所有这些 10s)。
我认为解决这个问题的方法只是使 layout
成为 int *
的数组(调整分配代码以适应),然后将 ret
直接分配给每个元素。
问题是您使用的是 int* 数组,而您真正想要的是 int 数组。每次存储 ret
时,您都在存储相同的地址。当您检查循环中的值时,它将是正确的,因为 ret
包含您想要的值...直到下一次迭代。
我从一个文件中读取整数值,通过 space 字符解析它们,然后将它们插入到一个名为 game 的结构中的 int** 中。使用 print 语句,我已经确认正确的值被放置在 int** 的正确位置,但是一旦我离开 while 循环或 return 结构,打印的值是错误的。
我的结构:
typedef struct Map_s{
char * defender;
char * attacker;
int missles;
int ** layout;
size_t capacity;
size_t size;
}map;
结构初始化:
map * newGame(){
map * game = malloc(sizeof(map));
game->layout = (int**)malloc(_DEFAULT_MAP_SIZE * sizeof(int*));
game->defender = NULL;
game->attacker = NULL;
game->missles = 0;
game->capacity = _DEFAULT_MAP_SIZE;
game->size = 0;
return game;
}
文件解析:
map * game = newGame();
char * token;
char * dup;
char * ptr;
int ret;
const char delim[2] = " ";
char * buf = NULL;
char * temp = NULL;
size_t size = _MAX_SIZE;
int lineNum = 1;
while( getline(&temp, &size, fp) > 1 ){
buf = strtok(temp, "\n");
dup = strdup(buf);
if( buf[0] != '#' ){
if( lineNum == 1){
if( game->defender == NULL ){
game->defender = dup;
}
}
else if( lineNum == 2 ){
if( game->attacker == NULL )
game->attacker = dup;
}
else if( lineNum == 3 ){
game->missles = atoi(dup);
}
else if( lineNum > 3 ){
token = strtok(dup, delim);
while( token != NULL ){
if( game->size >= game->capacity ){
game->layout = (int**)realloc(game->layout, \
game->capacity*2 * sizeof(int*));
game->capacity = game->capacity * 2;
}
ret = (int)strtol(token, &ptr, 10);
game->layout[game->size] = &ret;
game->size = game->size + 1;
token = strtok(NULL, delim);
//printf("%s ", token);
}
}**
lineNum++;
}
}
return game;
我几乎可以肯定我的代码在第二个 while 循环中的某个地方搞砸了。我正在尝试将字符串转换为整数,然后将其保存到 int** 中的正确位置。
我如何从 main 打印:
for( size_t i = 0; i < thisgame->size; i++ ){
printf("%d ", *thisgame->layout[i]);
if( i == 0)
continue;
else if( (i+1) % 10 == 0 )
printf("\n");
}
returning 结构后主函数的输出:
0 0 0 0 0 0 0 0 0 0
10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10
输出应该是什么样的(文件中有什么):
2 2 2 2 2 2 2 2 2 2
2 2 6 6 7 7 7 5 5 2
2 2 7 7 7 2 2 17 17 17 2
2 2 2 2 2 2 2 2 2 2
8 8 8 6 6 6 9 9 9 2
2 2 2 2 2 2 2 2 2 2
10 10 10 4 4 9 9 9 2
2 2 2 2 2 2 2 2 2 2
3 3 3 6 6 6 9 9 9 2
3 3 3 6 6 6 9 9 9 2
2 2 2 2 2 2 2 2 2 2
我发现了几个问题。
首先是行 **token = strtok(dup, delim);
。在此行的第一个 运行 处,token
没有有效值,因此取消引用它不是一次,而是两次,也会导致问题。我相信这应该只是 token = strtok(dup, delim);
这将导致 if 块中的 while 循环的第一次迭代到 return 错误值(至少所有这些 0 似乎符合这个猜测)。
其次是 D Go 指出的,因为您给出了 ret
的地址(该地址不会改变),因此 game->layout
的每个元素都具有相同的地址,并且因此查看相同的 int (适合所有这些 10s)。
我认为解决这个问题的方法只是使 layout
成为 int *
的数组(调整分配代码以适应),然后将 ret
直接分配给每个元素。
问题是您使用的是 int* 数组,而您真正想要的是 int 数组。每次存储 ret
时,您都在存储相同的地址。当您检查循环中的值时,它将是正确的,因为 ret
包含您想要的值...直到下一次迭代。