Realloc 现有数据丢失

Realloc existing data is getting lost

我正在学习c编程语言。下面的程序将命令的输出保存到变量中并打印出来。但是当重新分配内存以扩展内存时,我丢失了旧数据。

你能告诉我这里缺少什么吗?

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main(){

FILE *fp;

char r[1024];
fp=popen("/bin/ls /etc/","r");

if(fp==NULL){
    perror("Failed to run the command");
    exit(-1);
}

int totallengthread=0,alloc_size=1024;
char *buffer = (char*) malloc(alloc_size*sizeof(char));
memset(buffer,0,sizeof(buffer));
int lenofbuff=0;
while(fgets(r,1023,fp)!=NULL){
 concat(buffer,r);
 lenofbuff=strlen(buffer);
 totallengthread+=lenofbuff;
 if(totallengthread>=alloc_size){
     alloc_size+=1024;
     realloc(buffer,alloc_size);
 }

}
pclose(fp);
printf("this is the out put =>%s",buffer);
free(buffer);
 return 0;
}
void concat(char *dest, const char *source){
    char *d=dest;
    char *s=source;
    while (*d != '[=10=]') {
              d++;
           }
     while(*s!='[=10=]')
        {
            *d++=*s++;
        }
    *d='[=10=]';
}

realloc() 是通用内存重新分配的构建块。

代码需要使用 realloc() 中的 return 值,因为它是成功时指向重新分配数据的指针。

void * tptr = realloc(buffer, alloc_size);
// Detect out-of-memory 
if (tptr == NULL && alloc_size > 0) {
  // Handle it in some way
  fprintf(stderr, "Memory allocation failure\n");
  exit(EXIT_FAILURE);
}

buffer = tptr;

注意:存在各种其他非分配代码问题。

我觉得这更接近你想要的。请看代码中的注释。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

void concat(char *dest, const char *source){
    char *d=dest;
    char *s=source;
    while (*d != '[=10=]'){
        d++;
    }
    while(*s!='[=10=]'){
        *d++=*s++;
    }
    *d='[=10=]';
}

int main(){
    FILE *fp;
    char r[1024];
    fp=popen("/bin/ls /etc/","r");
    if(fp==NULL){
        perror("Failed to run the command");
        exit(-1);
    }
    int totallengthread=0,alloc_size=1024;
    char *buffer = malloc(alloc_size*sizeof*buffer); //This is nicer because is type independent
    memset(buffer,'[=10=]',sizeof*buffer); //I believe this is what you wanted.
    int lenofbuff=0;
    while(fgets(r,sizeof r,fp)){ // as @chux said this avoids hardcoding 1024-1. You also don't need to compare to NULL. 
        concat(buffer,r);
        lenofbuff=strlen(buffer);
        totallengthread+=lenofbuff;
        if(totallengthread>=alloc_size){
            alloc_size+=1024;
            buffer = realloc(buffer,alloc_size); //you need to use the return of realloc
        }
    }
    pclose(fp);
    printf("this is the out put =>%s",buffer);
    free(buffer);
    return 0;
}

正如@chux 提到的,在任何内存分配中,您应该检查返回的指针是否为 NULL,这将意味着分配失败。

此外,请注意

memset(buffer,'[=11=]',sizeof*buffer);

等同于

memset(buffer,0,sizeof*buffer);

正如@thebusybee 提到的,这只是将数组的第一个元素设置为 NULL 字符,如果你打算填充整个数组,你应该这样做 内存集(缓冲区,0,alloc_sizesizeof缓冲区);

或只是替换

char *buffer = malloc(alloc_size*sizeof*buffer);
memset(buffer,0,alloc_size*sizeof*buffer);

对于

char *buffer = calloc(alloc_size,sizeof*buffer);