重新分配一个双精度数组

Realloc an array of double

我必须完成的练习说:

That array_remove function must remove from the array arr the value, that is in the position pos, and scale of a position successive values of pos, and eventually change the array size for no gaps. If this value is not included in the array (if pos is greater than pn (array size)), then you should not do anything.

我的问题是:

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

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);
    }
}

根据 C 文档:

realloc Reallocates the given area of memory that must be previously allocated by malloc(), calloc() or realloc() and not yet freed with free, otherwise, the results are undefined.

当您 i=x-1 尝试访问 arr[i+1] = arr[x=pn] 时,以下几行也有越界问题:

for (int i = y; i < ; i++) {
    arr[i] = arr[i + 1]; 

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

  #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);


}

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

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

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

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。

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

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);

切勿通过指针传递值,除非您打算修改它。这里不是这种情况,所以你可以按值传递它。