使用 realloc 时程序崩溃
program crashes while using realloc
我得到了一个未知大小的文本文件,我必须阅读它直到最后,计算单词、字母和其他一些东西的数量。为此,我尝试读取整个文件并将所有单词保存在一个数组中。我被告知要使用动态内存分配,因为我事先不知道文本文件的大小。
在我进入计算单词和字母的算法之前,我试图让动态内存分配工作。这是我的代码:
int main(int argc, char *argv[]) {
FILE *fp; // file pointer
//defining a dynamic string array
char **array = malloc(10 * sizeof(char *)); //10 rows for now, will be dynamically changed later
int i,size = 10, current = 0; // current points to the position of the next slot to be filled
for(i=0; i<10; i++){
array[i] = malloc(20); //the max word size will be 20 characters (char size = 1 byte)
}
fillArray(fp, array, current, size);
return 0;
}
我定义了一个字符串数组,一个显示其大小的变量,以及一个指向将添加下一个元素的槽的变量。
功能如下:
int fillArray(FILE *fp, char **p, int ptr, int size){
puts("What's the name of the file (and format) to be accessed?\n (It has to be in the same directory as the program)");
char str[20];
gets(str); //getting the answer
fp = fopen((const char *)str, "r"); //opening file
int x=0, i=0, j;
while(x!=EOF){ // looping till we reach the end of the file
printf("current size: %d , next slot: %d\n", size, ptr);
if(ptr>=size){
printf("increasing size\n");
addSpace(p, &size);
}
x = fscanf(fp, "%19s", p[i]);
puts(p[i]);
i++;
ptr++;
}
}
void addSpace(char **p, int *size){ //remember to pass &size
//each time this is called, 10 more rows are added to the array
p = realloc(p,*size + 10);
int i;
for(i=*size; i<(*size)+10; i++){
p[i] = malloc(20);
}
*size += 10;
}
void freeSpace(char **p, int ptr){
//each time this is called, the rows are reduced so that they exactly fit the content
p = realloc(p, ptr); //remember that ptr points to the position of the last occupied slot + 1
}
一开始,数组的行数是10,每次文本中的单词不适合数组,就调用函数addSpace
,增加10行。程序成功运行3次(达到30行)然后崩溃
在使用 printf 找出程序崩溃的位置后(因为我还不习惯调试器),它似乎在尝试再添加 10 行(到 40)时崩溃了。我无法弄清楚问题或如何解决它。感谢任何帮助。
C是按值传递。指针 p
传递给 addSpace(p, &size);
,并在函数中创建该指针的副本。更改副本后:p = realloc(p,*size + 10);
原件保持不变。
realloc 调用后,原来的指针不再有效。使用它会导致未定义的行为,在您的情况下会导致崩溃。
Return新值并将其赋给原指针:
p = addSpace( p , &size );
经典!
您还传递了一个双指针,它是 realloc
d,地址在调用者和被调用者之间发生了变化。
还有一个 realloc
问题。
p = realloc(p,*size + 10);
如果 realloc
失败,指向内存块的原始指针将被破坏。
正确的做法:
char **tmp_ptr = realloc(p, *size + 10);
if (tmp_ptr == NULL){
perror("Out of memory");
}else{
p = tmp_ptr;
}
return p;
你可以用另一种方式,return返回新块的地址或使用三重指针。
void addSpace(char ***p, int *size){ //remember to pass &size
//each time this is called, 10 more rows are added to the array
char **tmp_ptr = realloc(*p, *size + 10);
if (tmp_ptr == NULL){
perror("Out of memory");
}else{
*p = tmp_ptr;
}
int i;
for(i=*size; i<(*size)+10; i++){
*p[i] = malloc(20);
}
*size += 10;
}
来自来电者
addSpace(&p, &size);
我得到了一个未知大小的文本文件,我必须阅读它直到最后,计算单词、字母和其他一些东西的数量。为此,我尝试读取整个文件并将所有单词保存在一个数组中。我被告知要使用动态内存分配,因为我事先不知道文本文件的大小。
在我进入计算单词和字母的算法之前,我试图让动态内存分配工作。这是我的代码:
int main(int argc, char *argv[]) {
FILE *fp; // file pointer
//defining a dynamic string array
char **array = malloc(10 * sizeof(char *)); //10 rows for now, will be dynamically changed later
int i,size = 10, current = 0; // current points to the position of the next slot to be filled
for(i=0; i<10; i++){
array[i] = malloc(20); //the max word size will be 20 characters (char size = 1 byte)
}
fillArray(fp, array, current, size);
return 0;
}
我定义了一个字符串数组,一个显示其大小的变量,以及一个指向将添加下一个元素的槽的变量。 功能如下:
int fillArray(FILE *fp, char **p, int ptr, int size){
puts("What's the name of the file (and format) to be accessed?\n (It has to be in the same directory as the program)");
char str[20];
gets(str); //getting the answer
fp = fopen((const char *)str, "r"); //opening file
int x=0, i=0, j;
while(x!=EOF){ // looping till we reach the end of the file
printf("current size: %d , next slot: %d\n", size, ptr);
if(ptr>=size){
printf("increasing size\n");
addSpace(p, &size);
}
x = fscanf(fp, "%19s", p[i]);
puts(p[i]);
i++;
ptr++;
}
}
void addSpace(char **p, int *size){ //remember to pass &size
//each time this is called, 10 more rows are added to the array
p = realloc(p,*size + 10);
int i;
for(i=*size; i<(*size)+10; i++){
p[i] = malloc(20);
}
*size += 10;
}
void freeSpace(char **p, int ptr){
//each time this is called, the rows are reduced so that they exactly fit the content
p = realloc(p, ptr); //remember that ptr points to the position of the last occupied slot + 1
}
一开始,数组的行数是10,每次文本中的单词不适合数组,就调用函数addSpace
,增加10行。程序成功运行3次(达到30行)然后崩溃
在使用 printf 找出程序崩溃的位置后(因为我还不习惯调试器),它似乎在尝试再添加 10 行(到 40)时崩溃了。我无法弄清楚问题或如何解决它。感谢任何帮助。
C是按值传递。指针 p
传递给 addSpace(p, &size);
,并在函数中创建该指针的副本。更改副本后:p = realloc(p,*size + 10);
原件保持不变。
realloc 调用后,原来的指针不再有效。使用它会导致未定义的行为,在您的情况下会导致崩溃。
Return新值并将其赋给原指针:
p = addSpace( p , &size );
经典!
您还传递了一个双指针,它是 realloc
d,地址在调用者和被调用者之间发生了变化。
还有一个 realloc
问题。
p = realloc(p,*size + 10);
如果 realloc
失败,指向内存块的原始指针将被破坏。
正确的做法:
char **tmp_ptr = realloc(p, *size + 10);
if (tmp_ptr == NULL){
perror("Out of memory");
}else{
p = tmp_ptr;
}
return p;
你可以用另一种方式,return返回新块的地址或使用三重指针。
void addSpace(char ***p, int *size){ //remember to pass &size
//each time this is called, 10 more rows are added to the array
char **tmp_ptr = realloc(*p, *size + 10);
if (tmp_ptr == NULL){
perror("Out of memory");
}else{
*p = tmp_ptr;
}
int i;
for(i=*size; i<(*size)+10; i++){
*p[i] = malloc(20);
}
*size += 10;
}
来自来电者
addSpace(&p, &size);