我正在学习C并尝试构建动态数组。我找到了一个很好的教程,但我没有完全理解。我现在的代码是
typedef struct{
int size;
int capacity;
char *data;
}Brry;
void brry_init(Brry *brry){
brry->size = 0;
brry->capacity = 2;
brry->data = (char *)calloc(brry->capacity, sizeof(char));
}
void brry_insert(Brry *brry, char value){
brry->data[brry->size++] = value; //so do check here if I have enough memory, but checking something out
}
int main(void){
Brry brry;
brry_init(&brry);
for (int i = 0; i < 3; i++) {
brry_insert(&brry, 'a');
}
printf("%c\n", brry.data[2]);
return 0;
}
在我的main函数中,我向数组中添加了3个元素,但它只分配给了2.但是当我打印它时它工作正常吗?我期待打印一些奇怪的价值。为什么这样或者我做错了什么?
答案 0 :(得分:3)
您正在写入一个没有为其分配足够内存的缓冲区。它无法保证。
你现在正在尝试的是从内存中的一些垃圾值中读取,谁知道,这有时会导致分段错误,有时候你很幸运并获得一些垃圾值,而且它不会发生段错误。
写入垃圾内存将调用未定义的行为,因此最好观看它。 如果你确实遇到错误,它几乎总是一个段错误,是分段错误的缩写。 阅读here。
通过读取数组边界所做的技术称为derefencing指针。您可能还想了解有关here的更多信息。
答案 1 :(得分:1)
是的,您确实正在写入双元素数组的第三个元素。这意味着您的程序将显示未定义的行为,并且您无法保证将会发生什么。在你的情况下,你很幸运,程序“工作”,但你可能并不总是那么幸运。
答案 2 :(得分:1)
尝试读取/写入数组末尾会导致未定义的行为。究竟发生了什么取决于几个你无法预测或控制的因素。有时,它似乎没有抱怨就能成功阅读和/或写入。其他时候,它可能会失败并且有效地使您的程序崩溃。
关键是你绝不应该尝试使用或依赖未定义的行为。不幸的是,这是一个常见的新手错误,认为它总是有效,因为一次测试碰巧成功了。这绝对不是这样,迟早会成为灾难的秘诀。