动态创建的数组大小不匹配

时间:2015-03-10 06:44:54

标签: c++ c arrays malloc

我想我错过了一些简单的东西,但我无法理解为什么会出现这个错误。

我有一个数组,其中包含我想要转换为double的原始数据。我也有这个数组的大小:

resWavFile0.resampledSingalData // array with data
resWavFile0.length // size of my array

如果我想显示它,那么它可以工作:

for (int i = 0; i < resWavFile0.length; i++) 
{
    cout << "\n" << *((int*)resWavFile0.resampledSingalData+i) / (double)0x7fffffff;
}

根本没有崩溃,我将所有值显示为double。但是现在我想将这些值保存在单独的数组中,所以我创建了:

double* singnalToProcess0;

因为resWavFile0.length可能会改变,我需要动态分配我的数组:

singnalToProcess0 = (double*) malloc(resWavFile0.length * sizeof(double));

此外,我可以将每个内存块的值设置为0:

memset(singnalToProcess0, 0, resWavFile0.length * sizeof(double));

但现在我想插入我的双打内容:

for (int i = 0; i < resWavFile0.length; i++) 
{
    *(singnalToProcess0 + i) = *((int*)resWavFile0.resampledSingalData+i) / (double)0x7fffffff;
}

例如我的resWavFile0.length值是149077,但我得到&#34; 0xC0000005:访问冲突读取位置0x01f6d000)在i = 75074.如果我尝试在malloc中扩展数组的大小,例如,即使像这样:< / p>

singnalToProcess0 = (double*) malloc( 30* resWavFile0.length * sizeof(double));

我仍然在75074得到相同的错误。如果我使用其他样本例如更短或更长 - 它总是在迭代中间附近出现此错误。静态分配也不起作用:

double* singnalToProcess0 = new double[149077];

在中间附近崩溃 - 在i = 75074 ...

那里有完整的代码:

//// transfer to double
singnalToProcess0 = (double*) malloc(resWavFile0.length * sizeof(double));
memset(singnalToProcess0, 0, resWavFile0.length * sizeof(double));

for (int i = 0; i < resWavFile0.length; i++) {
    *(singnalToProcess0 + i) = *((int*)resWavFile0.resampledSingalData+i) / (double)0x7fffffff;
}

我做错了什么?

编辑: ResampledWavFile结构:

typedef struct ResampledWavFile
{
    short* resampledSingalData;
    int length;
} ResampledWavFile;

Edit2现在可行:

for (int i = 0; i < resWavFile0.length; i++)
{
    singnalToProcess0[i] = resWavFile0.resampledSignalData[i] / (double)0x7fffffff;
}

Edit3:我错了,这也是可能的:

singnalToProcess0 = new double[resWavFile0.length];

4 个答案:

答案 0 :(得分:2)

您可能已经注意到崩溃的索引非常接近数组的一半。这并非巧合,因为您遇到的问题是由于您将短路数组(通常为2个字节长)转换为一个整数数组(通常为4个字节长)。像这样重写你的代码,它会起作用:

for (int i = 0; i < resWavFile0.length; i++) {
    *(singnalToProcess0 + i) = *((short*)resWavFile0.resampledSingalData+i) / (double)0x7fffffff; 
}

或完全删除强制转换(删除(short*)),因为实际上并不需要。

另外,您在评论中提到,由于您的数据具有动态大小,因此无法使用new。这也是不准确的,您可以在C ++中使用new代替malloc,通常应该这样做。

答案 1 :(得分:0)

考虑struct ResampledWavFile

的定义
typedef struct ResampledWavFile
{
    short* resampledSingalData;
    int length;
} ResampledWavFile;

并假设该类型的对象在length中有shortresampledSingalData个,行

for (int i = 0; i < resWavFile0.length; i++) 
{
    cout << "\n" << *((int*)resWavFile0.resampledSingalData+i) / (double)0x7fffffff;
}

看起来不对。

表达式

*((int*)resWavFile0.resampledSingalData+i)

相当于

int* ip = (int*)resWavFile0.resampledSingalData;
*(ip+i)

除非平台中有sizeof(short) == sizeof(int),否则将访问越界内存。

如果您将for循环中的行更改为:

    short num = resWavFile0.resampledSingalData[i];
    cout << "\n" << num / (double)0x7fffffff;

你可以避免这个问题。但是,我不明白这将如何影响数值计算的准确性。

答案 2 :(得分:0)

问题的答案取决于你真正需要做的事情。您没有清楚地解释它,但似乎有几种可能性,具体取决于resWavFile0.resampledSingalData数组和resWavFile0.length值的语义。只有你知道语义,我们在这里不是心灵感应或透视。

可能的解释包括(假设sizeof(int) == sizeof(short) * 2

  1. resWavFile0.resampledSingalData被声明为short个元素的数组。如果这些short元素是您的值,resWavFile0.length包含数组的长度,那么您需要的只是

    for (int i = 0; i < resWavFile0.length; i++)
      singnalToProcess0[i] = 
        resWavFile0.resampledSignalData[i] / (double) 0x7fffffff;
    
  2. 如果resWavFile0.resampledSingalData应该被重新解释为int值数组(由每个连续两个短路组成),但resWavFile0.length包含{{1}的长度数组,然后short应该是偶数,你需要的是

    resWavFile0.length
  3. 如果assert(resWavFile0.length % 2 == 0); for (int i = 0; i < resWavFile0.length / 2; i++) singnalToProcess0[i] = ((int *) resWavFile0.resampledSignalData[i]) / (double) 0x7fffffff; 应该被重新解释为resWavFile0.resampledSingalData值数组(由两个连续短路组成),int包含resWavFile0.length的长度}数组,然后你需要的是

    int

    但这与你原来的变种相同,它正在崩溃,显然这种解释是不正确的。

答案 3 :(得分:-3)

doubleintshort在内存中的大小不同。由于对齐内容和其他内存访问内容,访问内存增量(如*(singnalToProcess0 + i))无法获得所需的结果。 您应该像常规数组一样访问它们:singnalToProcess0[i] = ...。同样应该应用于*((int*)resWavFile0.resampledSingalData+i)以转向resWavFile0.resampledSingalData[i]

相关问题