我想我错过了一些简单的东西,但我无法理解为什么会出现这个错误。
我有一个数组,其中包含我想要转换为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];
答案 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
中有short
个resampledSingalData
个,行
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
)
resWavFile0.resampledSingalData
被声明为short
个元素的数组。如果这些short
元素是您的值,resWavFile0.length
包含数组的长度,那么您需要的只是
for (int i = 0; i < resWavFile0.length; i++)
singnalToProcess0[i] =
resWavFile0.resampledSignalData[i] / (double) 0x7fffffff;
如果resWavFile0.resampledSingalData
应该被重新解释为int
值数组(由每个连续两个短路组成),但resWavFile0.length
包含{{1}的长度数组,然后short
应该是偶数,你需要的是
resWavFile0.length
如果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)
double
,int
,short
在内存中的大小不同。由于对齐内容和其他内存访问内容,访问内存增量(如*(singnalToProcess0 + i)
)无法获得所需的结果。
您应该像常规数组一样访问它们:singnalToProcess0[i] = ...
。同样应该应用于*((int*)resWavFile0.resampledSingalData+i)
以转向resWavFile0.resampledSingalData[i]
。