神秘的段错虽然指针被初始化

时间:2017-03-14 12:51:32

标签: c pointers segmentation-fault malloc

我是C的新手,我正在尝试编写一个简单的文本编辑器,我已经编写了100行愚蠢的杂乱代码,但它只是起作用。直到这个SEGFAULT开始出现。我正在采用将终端切换到规范模式的方法,并从用户那里逐字逐句地获取并为每个人做必要的事情。这些字母被添加到缓冲区中,当缓冲区被填满一半时,该缓冲区被重新分配为512字节,我知道这是一个愚蠢的事情。但SEGFAULT的原因无法确定。帮助将不胜感激。这是我的代码:

char* t_buf
int t_buf_len = 0;
int cur_buf_sz = 0;

void mem_mgr(char *buffer, unsigned long bytes){ //Function to allocate requested memory
    if(buffer == NULL){
        if((buffer = malloc(sizeof(char) * bytes)) == NULL){
            printf("ERROR:Cannot get memory resources(ABORT)\n\r");
            exit(1);
        }
    }
    else{
        realloc(buffer, bytes);
    }
}

void getCharacter(){
    if(t_buf_len >= (cur_buf_sz/2))
        mem_mgr(t_buf, cur_buf_sz+=512);
    strcpy(t_buf, "Yay! It works!");
    printf("%s %d", t_buf, cur_buf_sz);
}

2 个答案:

答案 0 :(得分:2)

首先需要了解的事情,

  1. buffer指针是mem_mgr()函数中的局部变量,它最初指向相同的内存t_buf点,但是一旦你修改了它,它就会被指向t_buf指针。不再以任何方式与mem_mgr()相关。

    因此,当您从realloc()返回时,您将丢失对已分配内存的引用。

    要解决此问题,您可以将poitner传递给指针,并通过解除引用来更改实际指针。

  2. 如果第一个参数是malloc()NULL函数的行为与realloc()完全相同,如果您阅读了您将会知道的文档。

  3. 必须检查内存分配函数以确保它们返回一个有效的合法指针,这就是为什么你需要一个临时的poitner来存储NULL的返回值,因为如果它返回{{ 1}},意味着没有记忆来满足请求,你将失去对原始记忆块的引用,你就不能再释放它了。

  4. 您需要将指针传递给指向mem_mgr()的指针,就像这样

    int
    mem_mgr(char **buffer, unsigned long bytes)
    {
        void *tmp = realloc(*buffer, bytes);
        if (tmp != NULL) {
            *buffer = tmp;
            return 0;
        }
        return -1;   
    }
    

    然后,分配内存

    void
    getCharacter()
    {
        if (t_buf_len >= (cur_buf_sz / 2)) {
            if (mem_mgr(&t_buf, cur_buf_sz += 512) != -1) {
                strcpy(t_buf, "Yay! It works!");
                printf("%s %d", t_buf, cur_buf_sz);
            }
        }
    }
    

答案 1 :(得分:1)

致电

mem_mgr(t_buf, cur_buf_sz+=512);

无法更改实际参数t_buf。您将需要从mem_mgr

返回缓冲区
t_buf = mem_mgr(t_buf, cur_buf_sz+=512);

或传递指向t_buf

的指针
mem_mgr(&t_buf, cur_buf_sz+=512);

此外,对realloc的调用可能会更改内存缓冲区的地址,因此您必须使用

char *tmpbuf = realloc(buffer, bytes);
if (!tmpbuf)
    // Error handling
else
    buffer = tmpbuf;

realloc(NULL, bytes);的行为类似于malloc,因此您不需要在此处使用单独的分支。总而言之:

char *mem_mgr(char *buffer, unsigned long bytes){ //Function to allocate requested memory
    char *tmpbuf = realloc(buffer, bytes);
    if (!tmpbuf) {
         // Error handling
    }
    return tmpbuf;
}

以某种方式质疑函数mem_mgr存在的原因。