我必须完成的练习说:
array_remove
函数必须从数组arr
中删除位于pos
位置的值,以及位置连续值pos
的缩放,并最终更改数组大小没有间隙。 如果此值未包含在数组中(如果pos
大于pn
(数组大小)),那么您不应该执行任何操作。
我的问题是:
使用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);
}
}
答案 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)并检查删除后大小为零的边缘情况!
此外, 释放最后的内存并更新大小变量。
答案 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);
除非您打算修改它,否则永远不要通过指针传递值。不是这里的情况,所以你可以按值传递它。