重新分配一个double数组

时间:2016-02-11 09:57:10

标签: c arrays double realloc

我必须完成的练习说:

  

array_remove函数必须从数组arr中删除位于pos位置的值,以及位置连续值pos的缩放,并最终更改数组大小没有间隙。   如果此值未包含在数组中(如果pos大于pn(数组大小)),那么您不应该执行任何操作。

我的问题是:

使用malloc函数可能非常错误,因为执行它时会显示以下错误:

enter image description here

MAIN.C:

#include "array.h"

int main(void)
{
    double arr[] = { 1.0,2.0,3.0,4.0,5.0 };
    size_t pn = 5;/*array length*/
    size_t pos = 2;/*position of the number to be deleted*/

    array_remove(arr, &pn, pos);
}

ARRAY.C:

#include "array.h"

void array_remove(double *arr, size_t *pn, size_t pos)
{
    int x = *pn;
    int y = pos;
    if (x > y)
    {
        for (int i = y; i < x; i++)
        {
            arr[i] = arr[i + 1];
        }
        realloc(&arr, sizeof(double) * 4);
    }
}

3 个答案:

答案 0 :(得分:3)

根据C文档:

  

realloc 重新分配必须先前分配的给定内存区域   通过malloc(),calloc()或realloc()并且尚未释放,   否则,结果是不确定的。

当您尝试i=x-1 arr[i+1] = arr[x=pn] for (int i = y; i < ; i++) { arr[i] = arr[i + 1]; 时,您在以下行中也遇到了问题:

  #include<stdlib.h>

void array_remove(double **arr, int *pn, int pos) {
    int x = *pn;
    int y = pos;
    if (x > y) {
        //check if after deletion size is zero!
        if (x > y) {
            for (int i = y; i < x-1; i++) {
                (*arr)[i] = (*arr)[i + 1];
            }

            *arr=realloc(*arr, sizeof(double) * x-1);
            *pn=*pn-1;
        }
    }
}

int main(void) {
    int pn = 20;/*array length*/
    int pos = 5;/*position of the number to be deleted*/
    double *arr = malloc(sizeof(double)*pn);
    printf("%p\n",arr);
    for(int i=0;i<pn;i++){
        arr[i] = i;
    }

    for(int i=0;i<pn;i++){
        printf("%.f ",arr[i]);
    }
    printf("\n");

    printf("%i\n",pn);
    array_remove(&arr, &pn, pos);
    printf("%p\n",arr);
    for(int i=0;i<pn;i++){
        printf("%.f ",arr[i]);
    }
    printf("\n");
    printf("%i",pn);


    free(arr);


}

检查以下代码*(实时:https://ideone.com/mbSzjL

{{1}}

不要忘记使用正确的大小重新分配(不使用硬编码的4)并检查删除后大小为零的边缘情况!

此外, 释放最后的内存并更新大小变量。

http://en.cppreference.com/w/c/memory/realloc

答案 1 :(得分:2)

arr数组是堆栈分配的。你不能realloc不是malloc的东西。

你可能想要这样的东西:

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

bool array_remove(double **arr, size_t *pn, size_t pos)
{
    int x = *pn - 1;
    int y = pos;
    int i;
    double *temp;

    if (x > y) {
        for (i = y; i < x; i++) {
            (*arr)[i] = (*arr)[i + 1];
        }

        temp = realloc(*arr, sizeof(double) * x);
    }

    if (arr != NULL)
    {
        *arr = temp;

        *pn -=1;

        return true;
    }
    else
    {
        return false;
    }
}

int main(void)
{
    size_t pn = 5;  // array length
    size_t pos = 2; // position of the number to be deleted
    int i;

    double *arr = malloc(pn*sizeof(double));

    if (arr != NULL)
    {
        for (i=0; i<pn; i++)
        {
            arr[i] = (double)(i+1);
        }


        if (array_remove(&arr, &pn, pos) == false)
        {
            printf("Failed to remove element %zu\n", pos);
        }

        for (i=0; i<pn; i++)
         printf ("arr[%d]: %f\n", i, arr[i]);

        free(arr);
    }
    else
    {
        printf("Failed to alloc array\n");
    }

    return 0;
}

如您所见,我更改了array_remove的循环。在你的代码中,由于i=4,你在最后一个循环中对数组进行了解决,然后:     arr[i] = arr[i + 1];arr[4] = arr[5]

5个元素数组的索引从0到4开始。

答案 2 :(得分:0)

实际上你有一个不同的问题:

int x = *pn; //x=5
int y = pos; //y=2
if (x > y) {
        for (int i = y; i < x; i++) {
            arr[i] = arr[i + 1];
        }

在最后一次迭代中,你做

 arr[4] = arr[5]

这是超出范围的地址,这可能是您的问题,或者至少是您的问题。

此外,即使它在技术上没有错,但它在概念上是错误的:

array_remove(arr, &pn, pos);

除非您打算修改它,否则永远不要通过指针传递值。不是这里的情况,所以你可以按值传递它。