c - C中的全局变量丢失数据?
问题描述
我正在尝试创建一个字符串数组,其中每行(如果考虑矩阵)应该有 3 个任意长度的字符串,最多 10 行
数据结构是正确的,但我对全局变量中的输出感到非常惊讶。所以矩阵将作为程序的数据库,因此保存在全局空间中
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
// Maximum buffer size needed
#define MAX_NUM_ITEMS 10
#define MAX_ITEM_PER_ROW 3
static char *array[MAX_NUM_ITEMS][MAX_ITEM_PER_ROW];
#define ITOA_BASE_N (sizeof(unsigned)*CHAR_BIT + 1)
char *itoa_base(char *, int , int);
#define TO_BASE(x,b) itoa_base((char [ITOA_BASE_N]){0} , (x), (b))
char *itoa_base(char *s, int x, int base) {
s += ITOA_BASE_N - 1;
*s = '\0';
if (base >= 2 && base <= 36) {
int x0 = x;
do {
*(--s) = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[abs(x % base)];
x /= base;
} while (x);
if (x0 < 0) {
*(--s) = '-';
}
}
return s;
}
int main(void)
{
int count = 0;
for (int i = 0; i < MAX_NUM_ITEMS; i++){
for (int j = 0; j < MAX_ITEM_PER_ROW; j++ ){
++count;
array[i][j] = TO_BASE(count, 16);
}
}
for (int i = 0; i < MAX_NUM_ITEMS; i++){
for (int j = 0; j < MAX_ITEM_PER_ROW; j++ ){
printf("%s ",array[i][j]);
}
printf("\n");
}
return 0;
}
根据我的逻辑,我应该看到 1 2 3 4 5 6 7 8 9 等等,而不是 EEE
无法理解为什么会这样
解决方案
首先,这个:
(char [ITOA_BASE_N]){0}
不像 golang 那样,不会给你一个字符数组的新实例。因此,每次调用 itoa() 时,都会使用相同的字符数组调用它。更糟糕的是,字符数组占用了一个可回收的堆栈地址[它的范围只是那个内部循环],所以它可以在不久之后被随机的东西覆盖。但它非常一致。我会给它。
将调用更改为:
array[i][j] = strdup(TO_BASE(count, 16));
并在顶部添加 #include 会产生您想要的输出。
如果您的应用程序中不允许动态分配,您将不得不使用静态分配方案,您可以制作一个有界版本的 strdup,例如:
char *strnew(char *s) {
static char strspace[ITOA_BASE_N * MAX_NUM_ITEMS * MAX_ITEM_PER_ROW ];
static char *strnext = strspace;
if (strlen(s) + strspace >= &strspace[sizeof strspace]) {
s = "<error: out of space>"; /* something more clever is possible */
} else {
strcpy(strnext, s);
s = strnext;
strnext += strlen(strnext)+1;
}
return s;
}
你可以用它来代替 strdup。如果您帮下一个人一个忙,并使用基于计算的 MAX_STRING_SPACE 等更具描述性的概念;而不是插入“坏值”,导致某种异常,我相信他们会很感激。
推荐阅读
- laravel - 雄辩的关系和使用约束获取数据
- oracle - 如何将空值作为绑定参数传递
- javascript - 在表中使用 API 响应
- java - Java Collections.sort() 未按预期排序
- webdriver-io - webdriverio findelements 和 $$ 选项返回 Typescript 错误 getText is not a function
- java - ExoPlayer切换媒体源不黑屏
- python - 如何在python中将属性附加到geojson文件?
- c# - 将掩码添加到 ASPxTextBox 以仅查看值的最后 4 位
- docusignapi - 重定向 URL(在使用 API 的身份验证阶段)
- teradata - Teradata - “只读”数据库