C:数组未正确分配更多内存

C:数组未正确分配更多内存,c,arrays,C,Arrays,我对C相当陌生,我正在做一个项目。给定一个整数数组,我想将其中的所有零移到数组的左侧,其余元素按任意顺序移到所有零的右侧。我的算法的基本思想是计算数组中的零数,使用旧数组中的零数创建一个新数组,然后将剩余的非零整数“附加”到该数组中。然后我当然会打印成品 int main(int argc, const char * argv[]) { int a[10] = {3, 0, 1, 4, 0, 0, 7, 20, 1, 5}; int n = 10, count = 0;

我对C相当陌生,我正在做一个项目。给定一个整数数组,我想将其中的所有零移到数组的左侧,其余元素按任意顺序移到所有零的右侧。我的算法的基本思想是计算数组中的零数,使用旧数组中的零数创建一个新数组,然后将剩余的非零整数“附加”到该数组中。然后我当然会打印成品

int main(int argc, const char * argv[]) {
    int a[10] = {3, 0, 1, 4, 0, 0, 7, 20, 1, 5};
    int n = 10, count = 0;

    // counts the number of 0's in the original array
    for (int i = 0; i < n; ++i)
    {
        if (a[i] == 0)
        {
            ++count;
        }
    }

    // creates a new array and makes each element 0
    int *array = NULL;
    for (int j = 0; j < count; ++j)
    {
        array = realloc(array, (j + 1) * sizeof(int));
        array[j] = 0;
    }

    // adds the nonzero elements of the array to the new array
    for (int l = count; l < n; ++l)
    {
        array = realloc(array, l * sizeof(int)); // getting an error here
        if (a[l] != 0)
        {
            array[l+count] = a[l];
        }
    }

    // prints the array out in a nice format
    printf("%s", "{");
    for (int k = 0; k < n-1; ++k)
    {
        printf("%d%s", array[k], ",");
    }

    printf("%d", array[n-1]);
    printf("%s", "}\n");


    free(array);
    return 0;
}
int main(int argc,const char*argv[]{
inta[10]={3,0,1,4,0,0,7,20,1,5};
int n=10,计数=0;
//计算原始数组中0的数量
对于(int i=0;i

运行此代码时,我收到一个“线程1:EXC\u坏访问(代码=1,地址=0x40)”错误。我认为这是因为指向新数组的指针无效,但我不确定如何修复它。

在定义数组之前,计数是已知的。您可以使用malloc分配内存,如下所示

array = malloc( count * sizeof(int)).
该错误表示您正试图访问地址0x40。这表示其中一个指针已变为NULL,您正试图取消对ptr+0x40的引用

array[l+count] = a[l];
这将访问
数组
指向超出其分配大小的内存块。您必须使用第二个索引以不同的方式执行此操作:

// adds the nonzero elements of the array to the new array
int l = count;

for (int j=0; j < n; ++j)
{
    if (a[j] != 0)
    {
        array = realloc(array, (l+1) * sizeof(int));
        array[l] = a[j];
        ++l;
    }
}
//将数组的非零元素添加到新数组中
int l=计数;
对于(int j=0;j
关于您的算法: 我认为你不需要创建一个新的数组,只要使用
inttmp
作为交换区域,使用
intfoundzerocount
作为索引,你一次交换两个数字

关于内存分配: 如果要为固定大小的数组分配内存,只需使用
malloc()
分配一次数组,以后需要扩展数组时,只需调用
realloc()
一次即可

关于内存重置: 只需使用
memset()
,而不需要循环

关于c语言编程的建议 尝试改进您的c basic,特别是关于
数组
/
指针
/
内存
,并尝试从
glibc
了解更多函数


gnuclibrarydocument
这样的书我想会很有用。

其他答案解决了您当前的问题,即

            array[l+count] = a[l];
尝试访问
数组
指向的已分配空间的边界之外。我将把重点放在你解决问题的方法上,这是有缺陷的

动态内存分配相对昂贵。您不想做任何超出必要的事情,并且像您这样多次重新分配以每次小幅度增加,这是非常糟糕的形式

因为您在编译时知道需要多少元素,所以这里完全不需要动态分配。您可以这样做:

int a[10] = {3, 0, 1, 4, 0, 0, 7, 20, 1, 5};
int array[10] = { 0 };
(这里还要注意,当提供数组初始值设定项时,它没有显式初始化的所有数组元素都会初始化为
0


即使您在编译时不知道需要多少元素,在一个块中执行整个分配也要好得多。此外,如果通过
calloc()
执行此操作,则会自动初始化分配的空间,使其全部为零。

问题在于
数组[l+count]=a[l]正确分配完“零数组”后,其大小为3,然后尝试访问
(l+计数)
第六个位置,即6

即使你已经用内存解决了这些问题,它仍然不起作用,因为a[l]和更进一步的可能仍然是零。(你的初始数组中没有零,记得吗?)

这里有几个建议: 使用calloc()构建初始零数组,因为asman表示:

函数的作用是:为nmemb元素数组分配内存 每个字节的大小,并返回指向已分配内存的指针。这个 内存设置为零


首先分配,然后设置,因为使用内存的操作对性能来说非常费力。您最好先分配一些内存并使用它,而不是每一步都重新分配内存。在你开始砍掉之前,先花点时间考虑实际问题,你称之为:


计算数组中的零数,使用旧数组中的零数创建一个新数组,然后将剩余的非零整数“附加”到此数组中

您的注释说明了代码应该做什么,但代码却做了完全不同的事情。您解决问题的算法是错误的-这是错误的原因,而不是其他原因

首先,如果新数组应该包含旧数组的所有零加上所有非零,那么根据常识,新数组将始终具有与旧数组相同的大小。您甚至不需要使用动态内存分配
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

int main(int argc, const char * argv[]) {
    int a[10] = {3, 0, 1, 4, 0, 0, 7, 20, 1, 5};
    const int n = 10; 

    // counts the number of 0's in the original array
    int zeroes = 0;
    for (int i = 0; i < n; ++i)
    {
        if (a[i] == 0)
        {
            ++zeroes;
        }
    }

    // creates a new array and makes each element 0
    // there's actually no need to allocate this dynamically at all...
    int *array = calloc(1, sizeof(int[n]) ); 
    assert(array != NULL);

    // skip zeroes, ie "move the zeroes from the original array"
    int* not_zeroes = array + zeroes; // point at first item to contain "not zeroes"

    // adds the non-zero elements of the original array to the new array
    for (int i = 0; i < n; ++i)
    {
      if(a[i] != 0)
      {
        *not_zeroes = a[i]; 
        not_zeroes++;
      }
    }

    // prints the array out in a nice format
    printf("%s", "{");
    for (int i = 0; i < n; ++i)
    {
        printf("%d,", array[i]);
    }
    printf("}\n");


    free(array);
    return 0;
}