Iphone C语言中的内存分配问题
编辑2 在“我的另一个”中查找有关此问题的更多信息 编辑1 我更新了这篇文章,因此内容可能与Alexey、Hicham、Jonathan和Mat的评论不一致。Iphone C语言中的内存分配问题,iphone,objective-c,c,memory-management,Iphone,Objective C,C,Memory Management,编辑2 在“我的另一个”中查找有关此问题的更多信息 编辑1 我更新了这篇文章,因此内容可能与Alexey、Hicham、Jonathan和Mat的评论不一致。 2012-10-20 11:22:36.353 XX[4125:3e07] PRE POST FLOAT 4.000000 - 7979.000000 - 7979.000000 2012-10-20 11:22:36.358 XX[4125:3e07] PRE POST FLOAT 25.000000 - 539790632812373
2012-10-20 11:22:36.353 XX[4125:3e07] PRE POST FLOAT 4.000000 - 7979.000000 - 7979.000000
2012-10-20 11:22:36.358 XX[4125:3e07] PRE POST FLOAT 25.000000 - 53979063281237364484736793729327605401034441222848177467876829146104162439787488863720409331484927794377967278456986000075570355992521879340404128702782598833969629491268820332191001022225312452183861587484411698307560976546539765760.000000 - inf
2012-10-20 11:22:36.364 XX[4125:3e07] PRE POST FLOAT 32.000000 -
下面的代码用于协助开始检测。当该方法被调用一次时,一切正常,我得到了一个很好的值日志。当第二次调用该方法时,我得到nan
或junk。有什么想法吗
{
NSLog(@"Running onset.");
NSMutableArray *mutableArrayOfFlags = [[NSMutableArray alloc] init];
OnsetsDS *ods = malloc(sizeof *ods);
float* odsdata = (float*) malloc(onsetsds_memneeded(ODS_ODF_RCOMPLEX, 512, 11));
onsetsds_init(ods, odsdata, ODS_FFT_FFTW3_HC, ODS_ODF_RCOMPLEX, 512, 11, 44100);
int i;
int x;
bool onset;
for (i = 0; i < vocalBuffer.numFrames; i=i+512){
// convert vocal int to double
double (*vocalData)[2] = malloc(2 * 512 * sizeof(double));
for (x = 0; x < 512; x++){
*vocalData[x] = (double)vocalBuffer.buffer[i+x];
}
// init malloc output double
double (*outPutDoubleFFTData)[2];
outPutDoubleFFTData = malloc(2 * 512 * sizeof(double));
fft(512, vocalData, outPutDoubleFFTData);
int z;
// init malloc float fft data
float *floatFFTData;
floatFFTData = malloc(512 * sizeof(float));
for (z = 0; z < 512; z++){
floatFFTData[z] = (float)*outPutDoubleFFTData[z];
if (i==512*20) {
// NSLog(@"PRE POST %f - %f",*vocalData[z], floatFFTData[z]);
NSLog(@"PRE POST FLOAT %f - %f - %f",*vocalData[z], (*outPutDoubleFFTData)[z], floatFFTData[z]);
}
}
onset = onsetsds_process(ods, floatFFTData);
free((*outPutDoubleFFTData));
free(floatFFTData);
free(vocalData);
if (onset){
printf("onset --> %i\n", i);
NSNumber *integer = [[NSNumber alloc] initWithInt:i];
[mutableArrayOfFlags addObject:integer];
}
}
free(ods->data); // Or free(odsdata), they point to the same thing in this case
free(ods);
return [[NSArray alloc] initWithArray:mutableArrayOfFlags];
}
第二次调用消息时记录日志。
2012-10-20 11:22:36.353 XX[4125:3e07] PRE POST FLOAT 4.000000 - 7979.000000 - 7979.000000
2012-10-20 11:22:36.358 XX[4125:3e07] PRE POST FLOAT 25.000000 - 53979063281237364484736793729327605401034441222848177467876829146104162439787488863720409331484927794377967278456986000075570355992521879340404128702782598833969629491268820332191001022225312452183861587484411698307560976546539765760.000000 - inf
2012-10-20 11:22:36.364 XX[4125:3e07] PRE POST FLOAT 32.000000 -
您正在混合指针:
*doubleFFTData[b]
和double(*doubleFFTData)[2]
不匹配
如果需要两个512双精度阵列:
int b; double (*doubleFFTData)[2];
doubleFFTData[0] = calloc(1 , 2 * 512 * sizeof(double)); // initialize the array to 0
doubleFFTData[1] = doubleFFTData[0] + 512;
for (b = 0; b < 512;b++){
NSLog(@"results: %f", doubleFFTData[0][b]);
}
/*and : */
for (b = 0; b < 512;b++){
NSLog(@"results: %f", doubleFFTData[1][b]);
}
intb;双(*doubleFFTData)[2];
doubleFFTData[0]=calloc(1,2*512*sizeof(double));//将数组初始化为0
doubleFFTData[1]=doubleFFTData[0]+512;
对于(b=0;b<512;b++){
NSLog(@“结果:%f”,doubleFFTData[0][b]);
}
/*以及:*/
对于(b=0;b<512;b++){
NSLog(@“结果:%f”,doubleFFTData[1][b]);
}
double(*doubleFFTData)[2]
将doubleFFTData
定义为指向2个double
数组的指针
*doubleFFTData[b]
首先评估[b]
,然后评估*
由于doubleFFTData
作为指向2个double
数组的指针,doubleFFTData[b]
是2个double
数组的第b个数组
第二个数组加倍,第二个数组加倍,doubleFFTData[b]
,衰减为一个指针,指向第二个数组第0个元素的指针加倍。当您使用*
解除对该指针的引用时,您将获得两个指针中的第一个双指针
因此,*doubleFFTData[b]
相当于doubleFFTData[b][0]
,它获得表示复数DFT点的双精度对中的第一个双精度
那部分看起来不错
但是您没有初始化分配给malloc()
的内存malloc()
不会将分配的内存设置为任何预定值,因为C语言标准不需要它。因此,内存可以包含以前执行的代码中留下的任何数据,或者如果在电脑开机后内存还没有被使用,那么它可能只是纯粹的垃圾
您不想使用未初始化的变量。除非,您正在实现一个或多个。///我的评论与///
-(无效)objcMallocEx
{
NSLog(@“跑步开始”);
//obj-c分配
NSMutableArray*mutableArrayOfFlags=[[NSMutableArray alloc]init];
///我更希望在下面的调用中看到这一点,然后是&ods,并去掉底部的free
///OnsetsDS*ods=malloc(sizeof*ods);
OnsetsDS-ods=NULL;
///问:onsetsds_init()是否期望odsdata作为它可以填充的缓冲区?
///或者它希望您为它提供指向它将填充的指针的地址?
///如果是前者,那么你做了下面正确的事情。如果是后者,那么
///你真正需要的是
///float*odsdata=NULL;
///然后将&odsdata作为第二个参数传递给下一行的onsetsds_init()。
float*odsdata=(float*)malloc(onsetsds_memneeded(ODS_ODF_RCOMPLEX,512,11));
///onsetsds_init(ods、odsdata、ods_FFT_FFTW3_HC、ods_ODF_RCOMPLEX,512、1144100);
onsetsds_init(&ods,odsdata,ods_FFT_FFTW3_HC,ods_ODF_RCOMPLEX,512,11,44100);
int i;
int x;
布尔发作;
对于(i=0;i/// my comments are with ///
- (void)objcMallocEx
{
NSLog(@"Running onset.");
// an obj-c allocation
NSMutableArray *mutableArrayOfFlags = [[NSMutableArray alloc] init];
/// i would prefer to see this, followed by &ods in the call below, and get rid of the free at the bottom
/// OnsetsDS *ods = malloc(sizeof *ods);
OnsetsDS ods = NULL;
/// Q: is onsetsds_init() expecting odsdata as a buffer it can fill?
/// or is it expecting you to be providing it with the address to a pointer that it will fill?
/// if the former, then you've done the right thing below. if the latter, then
/// what you really need is
/// float* odsdata = NULL;
/// and then pass the &odsdata as the 2nd arg to onsetsds_init() on the next line.
float* odsdata = (float*) malloc(onsetsds_memneeded(ODS_ODF_RCOMPLEX, 512, 11));
/// onsetsds_init(ods, odsdata, ODS_FFT_FFTW3_HC, ODS_ODF_RCOMPLEX, 512, 11, 44100);
onsetsds_init(&ods, odsdata, ODS_FFT_FFTW3_HC, ODS_ODF_RCOMPLEX, 512, 11, 44100);
int i;
int x;
bool onset;
for (i = 0; i < vocalBuffer.numFrames; i=i+512){
/// in the assignment for the loop, you are declaring that you want an array
/// of 2 double* . but the malloc assignment is more like a single array
/// of 1024 double items. it seems like what you really want is 2 arrays of
/// 512 double items.
/// // convert vocal int to double
/// double (*vocalData)[2] = malloc(2 * 512 * sizeof(double));
double vocalData[2][512];
/// if you absolutely insist on using allocation for this, the closest
/// semantically declaration would be
/// double* vocalData[2] = { malloc(512) * sizeof(double)), malloc(512) * sizeof(double) }
/// or
/// double* vocalData[] = (double*)malloc(2 * sizeof(double*));
/// vocalData[0] = malloc(512) * sizeof(double);
/// vocalData[1] = malloc(512) * sizeof(double);
/// THE FOLLOWING IS PART I OF WHAT'S LEADING TO THE DISPLAY OF "RANDOM" DATA
///
/// now, according to your original declaration, you have an array of two pointer-to-double,
/// but in the loop below, c++ operator precedence means it will operate on [x] first, and then on
/// * . so ... you are getting what's at the xth pointer-to-double, and then getting the value of
/// of that. if x is 100, and sizeof(double)==8 and sizeof(pointer-to-double)==4, then you the
/// code below is acting as though it wants to get what's at the memory 400 bytes from vocalData,
/// but if you want the 100th double, you should be getting what's at the memory 800 bytes from
/// vocalData.
/// for (x = 0; x < 512; x++){
/// *vocalData[x] = (double)vocalBuffer.buffer[i+x];
/// }
for (x = 0; x < 512; x++)
vocalData[0][x] = (double)vocalBuffer.buffer[i+x];
/// or (*vocalData)[x] = (double)vocalBuffer.buffer[i+x];
/// if you absolutely insist on using pointer arithmetic for this, the closest
/// semantically correct code would be
/// for (x = 0; x < 512; x++)
/// *(vocalData+(sizeof(double)*x)) = (double)vocalBuffer.buffer[i+x];
/// again, with outPutDoubleFFTData, you are declaring that you want an array
/// of 2 double*, but the malloc assignment is more like a single array of
/// 1024 double items.
/// some of what is correct depends upon what the arg signature of fft() is ...
// init malloc output double
/// double (*outPutDoubleFFTData)[2];
/// outPutDoubleFFTData = malloc(2 * 512 * sizeof(double));
double outPutDoubleFFTData[2][512];
/// if you absolutely insist on using allocation for this, the closest
/// semantically equivalent declaration would be
/// double* outPutDoubleFFTData[2] = { malloc(512) * sizeof(double), malloc(512) * sizeof(double) }
/// or
/// double* outPutDoubleFFTData[] = (double*)malloc(2 * sizeof(double*));
/// outPutDoubleFFTData[0] = malloc(512) * sizeof(double);
/// outPutDoubleFFTData[1] = malloc(512) * sizeof(double);
fft(512, vocalData, outPutDoubleFFTData);
int z;
// init malloc float fft data
float *floatFFTData;
floatFFTData = malloc(512 * sizeof(float));
for (z = 0; z < 512; z++){
/// THE FOLLOWING IS PART II OF WHAT'S LEADING TO THE DISPLAY OF "RANDOM" DATA
/// and, again, according to the original declaration, below, if z == 100 and
/// sizeof(double)==8 and sizeof(double*)==4, then you'll be accessing the memory
/// at the location 400 away from outPutDoubleFFTData when what you really want is
/// the memory that's 800 away from outPutDoubleFFTData.
///
/// floatFFTData[z] = (float)*outPutDoubleFFTData[z];
///
floatFFTData[z] = (float)((*outPutDoubleFFTData)[z]);
if (i==512*20) {
// NSLog(@"PRE POST %f - %f",*vocalData[z], floatFFTData[z]);
/// here, you got the pointer arithmetic into outPutDoubleFFTData correct !!
/// the trouble is, what you stored there is unknown because of the calculations above !!!
NSLog(@"PRE POST FLOAT %f - %f - %f",*vocalData[z], (*outPutDoubleFFTData)[z], floatFFTData[z]);
}
}
onset = onsetsds_process(ods, floatFFTData);
/// the following isn't going to free what you allocated
/// free((*outPutDoubleFFTData));
/// to do that, you should have
/// free(outPutDoubleFFTData);
/// but best of all is to use the 2-d array in the stack, and then you won't need the heep
free(floatFFTData);
/// also don't need the following if using the simple array declaration instead
/// free(vocalData);
if (onset){
printf("onset --> %i\n", i);
NSNumber *integer = [[NSNumber alloc] initWithInt:i];
[mutableArrayOfFlags addObject:integer];
}
}
/// here, since you did a malloc into odsdata, the best thing to do would be to free
/// the same variable as well.
free(ods->data); // Or free(odsdata), they point to the same thing in this case
/// this isn't necessary if you use the code i've replaced above, rather than what
/// you had that is now commented out.
/// free(ods);
return [[NSArray alloc] initWithArray:mutableArrayOfFlags];
}
float *floatFFTData;
floatFFTData = malloc(512 * sizeof(float));
for (z = 0; z < 512; z++){
floatFFTData[z] = (float)*outPutDoubleFFTData[z];
if (i==512*20) {
// NSLog(@"PRE POST %f - %f",*vocalData[z], floatFFTData[z]);
NSLog(@"PRE POST FLOAT %f - %f - %f",*vocalData[z], (*outPutDoubleFFTData)[z], floatFFTData[z]);
}
}
OnsetsDS *ods = malloc(sizeof *ods);
OnsetsDS *ods = malloc(sizeof OnsetsDS);
OnsetsDS ods;