函数 ramdonly 工作,覆盖内存,双重释放,损坏 (!prev)
Function works ramdonly, overwriting memory, double free, corruption (!prev)
我正在学习 C 编程,我认为我做得很好,但是我已经尝试了几个小时,但我没有弄清楚我做错了什么。
我做了一个函数来打印一个数组,它工作正常但只是第一次,后来打印奇怪的字符 o 不起作用,gdb 看到它工作正常但是当我第二次调用 printArray 时,函数 integerToString 没有第二次工作。老实说,我不知道如何解决它,我请求一些帮助;-;我在问你的评论
下面的代码是一个最小的可重现示例,但我认为问题出在 seeArray 函数和 integerToString 函数中
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
//Dependecy
int randomInRange(int lower, int upper){
return (random() % (upper - lower + 1)) + lower;
}
//Dependecy
int countDigits(int num, int * numSize){
*numSize = 0;
do{
(* numSize)++;
num /= 10;
}while(num != 0);
return 0;
}
//Here is where things gets broke!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
int integerToString(int num, char** strNum, int* strNumSize){
countDigits(num, strNumSize);
*strNum = (char *) malloc(sizeof(char) * (*strNumSize));
if(*strNum == 0x0){
fprintf(stderr, "No enough memory for convert interger to string");
exit(EXIT_FAILURE);
}
for(int i = (*strNumSize-1); i > -1; i--){
*( (*strNum) + i ) = num%10 + '0';
num /= 10;
}
return 0;
}
//Dependecy
int initArray(int** array, int size){
if(size<1){
fprintf(stderr, "The array\'s size most be minimun one");
exit(EXIT_FAILURE);
}
*array = (int*) malloc(sizeof(int)*size);
if(*array == NULL){
fprintf(stderr, "Couldn\'t reserve memory for array");
exit(EXIT_FAILURE);
}
for(int i = 0; i < size; i++) *((*array)+i) == 0;
return 0;
}
//Here is where things gets broke!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
int seeArray(int* array, int size, char** arrayPhotography, int* arrayPhotographySize){
int dataSize = 0;
char* data = 0x0;
for(int i = 0; i < size; i++){
integerToString(*(array+i), &data, &dataSize);
*arrayPhotographySize += sizeof(char) * ( 2 + dataSize );
if(*arrayPhotography == 0x0){
*arrayPhotography = (char *) malloc(*arrayPhotographySize);
}else{
*arrayPhotography = (char *) realloc(*arrayPhotography,*arrayPhotographySize);
}
if(*arrayPhotography == 0x0){
fprintf(stderr,"Not enoug memory for array\'s photography");
exit(EXIT_FAILURE);
}
strcat(*arrayPhotography, "[");
strcat(*arrayPhotography, data);
strcat(*arrayPhotography, "]");
free(data);
data = 0x0;
}
free(data);
return 0;
}
//Dependecy
int printArray(int* array, int size){
int arrayPhotographySize = 0;
char* arrayPhotography = 0x0;
if(seeArray(array, size, &arrayPhotography, &arrayPhotographySize)){
fprintf(stderr, "Fuction printArray");
exit(EXIT_FAILURE);
}
printf("Array:%s\n", arrayPhotography);
free(arrayPhotography);
return 0;
}
//Here is where things gets broke!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
int main(int argc, char * argv[]){
srand(time(NULL));
int arraySize = randomInRange(1, 15);
int* array = 0x0;
initArray(&array, arraySize);
for (int i = 0; i < 10; i++){
printArray(array, arraySize);
}
free(array);
}
这是随机工作原理的图像(我认为是)
- 似乎在您的
initArray
函数中,在最后的 for 循环中,您将 ==
而不是 =
写入数组 zero-fill。附带一提,<stdlib.h>
header 中有一个函数 calloc
会自动为你 zero-fill 一个动态分配的数组,这对于避免像这样的简单错误很方便.
- 在您的
integerToString
函数中,您只 malloc
足够 space 来保存字符串中的位数。然而,这是 error-prone 代码,因为 C 中的大多数字符串操作(包括 strcat
)都要求字符串以空字符结尾。为一个额外的字符分配 space,然后确保最后一个字符为 0。
我正在学习 C 编程,我认为我做得很好,但是我已经尝试了几个小时,但我没有弄清楚我做错了什么。 我做了一个函数来打印一个数组,它工作正常但只是第一次,后来打印奇怪的字符 o 不起作用,gdb 看到它工作正常但是当我第二次调用 printArray 时,函数 integerToString 没有第二次工作。老实说,我不知道如何解决它,我请求一些帮助;-;我在问你的评论
下面的代码是一个最小的可重现示例,但我认为问题出在 seeArray 函数和 integerToString 函数中
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
//Dependecy
int randomInRange(int lower, int upper){
return (random() % (upper - lower + 1)) + lower;
}
//Dependecy
int countDigits(int num, int * numSize){
*numSize = 0;
do{
(* numSize)++;
num /= 10;
}while(num != 0);
return 0;
}
//Here is where things gets broke!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
int integerToString(int num, char** strNum, int* strNumSize){
countDigits(num, strNumSize);
*strNum = (char *) malloc(sizeof(char) * (*strNumSize));
if(*strNum == 0x0){
fprintf(stderr, "No enough memory for convert interger to string");
exit(EXIT_FAILURE);
}
for(int i = (*strNumSize-1); i > -1; i--){
*( (*strNum) + i ) = num%10 + '0';
num /= 10;
}
return 0;
}
//Dependecy
int initArray(int** array, int size){
if(size<1){
fprintf(stderr, "The array\'s size most be minimun one");
exit(EXIT_FAILURE);
}
*array = (int*) malloc(sizeof(int)*size);
if(*array == NULL){
fprintf(stderr, "Couldn\'t reserve memory for array");
exit(EXIT_FAILURE);
}
for(int i = 0; i < size; i++) *((*array)+i) == 0;
return 0;
}
//Here is where things gets broke!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
int seeArray(int* array, int size, char** arrayPhotography, int* arrayPhotographySize){
int dataSize = 0;
char* data = 0x0;
for(int i = 0; i < size; i++){
integerToString(*(array+i), &data, &dataSize);
*arrayPhotographySize += sizeof(char) * ( 2 + dataSize );
if(*arrayPhotography == 0x0){
*arrayPhotography = (char *) malloc(*arrayPhotographySize);
}else{
*arrayPhotography = (char *) realloc(*arrayPhotography,*arrayPhotographySize);
}
if(*arrayPhotography == 0x0){
fprintf(stderr,"Not enoug memory for array\'s photography");
exit(EXIT_FAILURE);
}
strcat(*arrayPhotography, "[");
strcat(*arrayPhotography, data);
strcat(*arrayPhotography, "]");
free(data);
data = 0x0;
}
free(data);
return 0;
}
//Dependecy
int printArray(int* array, int size){
int arrayPhotographySize = 0;
char* arrayPhotography = 0x0;
if(seeArray(array, size, &arrayPhotography, &arrayPhotographySize)){
fprintf(stderr, "Fuction printArray");
exit(EXIT_FAILURE);
}
printf("Array:%s\n", arrayPhotography);
free(arrayPhotography);
return 0;
}
//Here is where things gets broke!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
int main(int argc, char * argv[]){
srand(time(NULL));
int arraySize = randomInRange(1, 15);
int* array = 0x0;
initArray(&array, arraySize);
for (int i = 0; i < 10; i++){
printArray(array, arraySize);
}
free(array);
}
这是随机工作原理的图像(我认为是)
- 似乎在您的
initArray
函数中,在最后的 for 循环中,您将==
而不是=
写入数组 zero-fill。附带一提,<stdlib.h>
header 中有一个函数calloc
会自动为你 zero-fill 一个动态分配的数组,这对于避免像这样的简单错误很方便. - 在您的
integerToString
函数中,您只malloc
足够 space 来保存字符串中的位数。然而,这是 error-prone 代码,因为 C 中的大多数字符串操作(包括strcat
)都要求字符串以空字符结尾。为一个额外的字符分配 space,然后确保最后一个字符为 0。