c - 打印字符串会产生垃圾,即使(我认为)它们是空终止的

标签 c arrays string garbage null-terminated

当我运行 print_puzzle(create_puzzle(input)) 时,我在输出的底部看到了一堆乱码,仅在最后一行。我不知道为什么会这样。输出应该是 9 行,每行 9 个数字(输入是一个数独游戏,零代表空格)。

这组代码应该采用该输入,制作一个二维字符串数组,然后使用 print_puzzle,将这些字符串打印在网格中。它们是字符串,因为最终我将实现一种方法来显示正方形可能的所有值。但是现在,当我打印出来时,事情就搞砸了。我什至尝试将 null 值放入所有 81 个字符串的每个元素中,但在打印字符串时它仍然搞砸了。我迷路了!

typedef struct square {
  char vals[10]; // string of possible values
} square_t;

typedef struct puzzle {
  square_t squares[9][9];
} puzzle_t;

static puzzle_t *create_puzzle(unsigned char vals[9][9]) {
  puzzle_t puz;
  puzzle_t *p = &puz;
  int i, j, k, valnum;
  for (i = 0; i < 9; i++) {
    for (j = 0; j < 9; j++) {
      puz.squares[i][j].vals[0] = '\0';
      puz.squares[i][j].vals[1] = '\0';
      puz.squares[i][j].vals[2] = '\0';
      puz.squares[i][j].vals[3] = '\0';
      puz.squares[i][j].vals[4] = '\0';
      puz.squares[i][j].vals[5] = '\0';
      puz.squares[i][j].vals[6] = '\0';
      puz.squares[i][j].vals[7] = '\0';
      puz.squares[i][j].vals[8] = '\0';
      puz.squares[i][j].vals[9] = '\0';
      valnum = vals[i][j] -'0';
      for (k = 0; k < 10; k++){
        if ((char)(k + '0') == (char)(valnum + '0')){
          char tmpStr[2] = {(char)(valnum +'0'),'\0'};
          strcat(puz.squares[i][j].vals, tmpStr);
        }
      }
    }
  }
  return p;
}

void print_puzzle(puzzle_t *p) {
  int i, j;
  for (i=0; i<9; i++) {
    for (j=0; j<9; j++) {
      printf(" %2s", p->squares[i][j].vals);
    }
    printf("\n");
  }
}

最佳答案

简而言之: 在函数 create_puzzle() 中,您将返回一个指向局部变量 puz 的指针。局部变量只知道在它们自己的内部起作用。所以create_puzzle返回的指针所引用的内容是不确定的。

更多详情: 在 C++ 中,局部变量通常生成为存储在“堆栈”数据结构上。当 create_puzzle() 方法被输入时,它的局部变量被激活。当方法结束时,函数的局部变量将死亡。 C++ 的实现不需要让您留在堆栈上的垃圾保持原样,这样您就可以访问它的原始内容。 C++ 不是一种安全的语言,它的实现会让你犯错并侥幸逃脱。其他内存安全语言通过限制你的权力来解决这个问题。例如,在 C# 中,您可以获取本地地址,但该语言设计巧妙,因此在本地生命周期结束后无法使用它。

这个答案非常棒: Can a local variable's memory be accessed outside its scope?

关于c - 打印字符串会产生垃圾,即使(我认为)它们是空终止的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33121447/

相关文章:

c++ - 返回 const 指针(例如 int * const)的函数的用例是什么?

CHAR_WIDTH 未声明

c# - LINQ可以构造并返回一个多维数组吗

arrays - 在 Bash 中循环遍历字符串数组?

PHP XML 到具有属性和值的数组/对象

c++ - C++ 中的排序字符串不能正确比较?

string - 就地替换字符串中的模式

python - argc 始终为零

c - 使用用户确定的填充打印 int 值?

java - 在Java中将字符串绘制到图像