首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >free()函数在几个memmove之后导致崩溃

free()函数在几个memmove之后导致崩溃
EN

Stack Overflow用户
提问于 2014-11-28 15:44:46
回答 1查看 298关注 0票数 0

我正在编写一个与js中的splice函数类似的函数:给定一个数组(任何类型),删除从给定索引开始的一些元素,并在间隙中填充一些新元素(如果需要,可以展开或舍弃原始数组)。

我在Windows7下使用MinGw/Eclipse。这是我的代码:

代码语言:javascript
复制
void* splice(int typesize,void* arr,
        int size,int start, int length,
            void* stuff,int size2){
    //length is the number of elements to remove
    //and size2 is the number of elements to fill in the gap

    //so size-gap will be the size of the new array after the function
    //when gap is a minus number, the array grows
    //and when gap is a positive number, the array shrinks
    int gap = length-size2;
    void* ptr = malloc(typesize*(size-gap));//--------(1)--------
    if(ptr==NULL){
        puts("error");
        return NULL;
    }
    //now the ptr array is empty, copy the original array(arr)
    //to the ptr until the 'start' index
    memmove(ptr,arr,typesize*start);

    //fill the new array 'stuff' into ptr starting from 
    //the index after 'start'
    memmove(ptr+typesize*start,stuff,typesize*size2);

    //and copy the rest of the original array (starting from 
    //the index start+length, which means starting from 'start' index
    //and skip 'length' elements) into ptr
    memmove(ptr+typesize*(start+size2),arr+typesize*(start+length),
            typesize*(size-start-length));

    return ptr;
}

我还编写了一些测试代码,下面的代码片段用于long long类型:

代码语言:javascript
复制
int main(){
    setbuf(stdout,NULL);
    int start = 1;
    int delete = 6;
    long long* oldArray= malloc(sizeof(long long)*7);
    long long* stuff = malloc(sizeof(long long)*3);
    oldArray[0]=7LL;
    oldArray[1]=8LL;
    oldArray[2]=4LL;
    oldArray[3]=1LL;
    oldArray[4]=55LL;
    oldArray[5]=67LL;
    oldArray[6]=71LL;
    stuff[0]=111LL;
    stuff[1]=233LL;
    stuff[2]=377LL;
    int newsize = 7-(delete-3);
    void* newArray = splice(sizeof(long long),oldArray,7,start,delete,stuff,3);
    if(newArray){

        //------------crash happens here-----------
        //free(oldArray);
        //-------------

        oldArray =  newArray;
        int i=0;
        for(;i<newsize;i++){
            printf("%I64d\n",oldArray[i]);
        }
    }
    return 0;
}

它应该输出7、111、233和377 (从索引1中删除6个元素,并将111,233和377填充到数组中)。

我测试了char、int和长类型数组,在所有情况下代码都正常工作。除了一个问题:我不能释放旧的数组。它表明,一旦memmove多次访问该内存块,就无法回收它。

如果我将malloc更改为realloc at (1),并且free()不会崩溃,但我不能再使函数正常工作(而且我不确定free()函数是否真的工作)。

请给出一些关于这个问题是如何产生的,以及如何改进我的代码。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-11-28 15:57:17

看看这一行:

代码语言:javascript
复制
    memmove(ptr,arr,typesize*size);

它尝试将类型大小*大小字节移动到ptr。但是您只分配了类型大小*(大小间隙)字节。这将导致崩溃,如果差距>0,除非你是非常不幸的。

在我发现第一个bug之后,我就停止了检查,所以可能会有更多的错误,而且我也没有费心地找出代码是做什么的。您应该添加一个注释,它描述了函数应该做得足够好,这样我就可以实现它,而无需猜测或问您问题。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27192040

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档