【问题标题】:Loop will not increment past 8?循环不会增加超过 8?
【发布时间】:2011-03-10 13:36:53
【问题描述】:

我有一个涉及 C 中动态分配的数组的循环。由于某种原因,它在 flag 增加 7 次后崩溃。在我重新分配数组的大小之前,这并没有发生。代码如下:

for (int i = 0; i < length-1; i++) 
{

    if (audio_samples[i] > threshold  && run) 
    {

        *event_flags = (int*)realloc(*event_flags, sizeof(int)*(flag+1)); // reallocate the size of the array
        *event_flags[flag] = i;
        // printf("FLAG CREATED! %i\n ", i);
        printf("EVENT FLAG %i  %i\n",flag, *event_flags[flag] );
        if (flag >5) {
            printf("%d\n", i);
        }

        flag++;
        run = false;
    }   

有什么想法吗?请记住,数组的大小确实与长度相同。这是我的错误的一个例子:


编辑 1

文件一:

   int *event_positions = (int *) malloc(1 * sizeof(int)); // let us start with 1 and then add more within the method. This should continue until we have all the flags we want.  
   int number_of_flags = event_extractor(vocal_data, size, event_positions);

文件二:

 float g_THRESHOLD_FACTOR = 2.3; // THIS INCREASES THE THRESHOLD VALUE.


 int event_extractor (int *audio_samples, unsigned int size_of_audio ,int *event_flags)
 {

int length = (int)size_of_audio;


// * * * * * * * * * * * * * * * * * * 
// RECTIFY VALUES (MAKE ABSOLUTE) (MAKE ALL POSITIVE)
int *rectified_audio = (int *) malloc(length * sizeof(int)); // I took this line from wave header reader. The number is the number of samples of the hip hop track.
make_values_absolute(audio_samples, length, rectified_audio);


   // If I convert to signed ints here would the method run more efficiently?   

// * * * * * * * * * * * * * * * * * * * *
// LOW PASS FILTER
int *lopass_samples = (int *) malloc(length * sizeof(int)); // I took this line from wave header reader. The number is the number of samples of the hip hop track.
lopass(rectified_audio, length,0.5, lopass_samples);



int number_of_flags = apply_threshold (lopass_samples, length, &event_flags);


printf("\n\n\n NUMBER OF EVENTS AAAA  --- %d\n", number_of_flags);

for (int i = 0; i < number_of_flags; i++) {
    printf("FLAG %i  -- %d \n", i, event_flags[i]);
}



return number_of_flags;
 }


 int apply_threshold (int *audio_samples, unsigned int size_of_audio, int **event_flags)
  {


int flag = 0; // this will be the number of flags that I have 
bool run = true; // this will make sure that a minimum amount of time passes before I grab another flag. It's a guard.
int counter = 0; // this is the counter for the above guard. 





printf("\n\nCURRENT MINIMUM TIME:  20100 SAMPLES \n\n");

// event_flags[0] = 1; // this first one is a dud. within the loop we will automatically start adding flags


int threshold = calculate_threshold_value(audio_samples, size_of_audio);

printf("\n\n this is the threshold %d \n\n", threshold);

int length = (int)size_of_audio;

printf("LENGTH OF VOCAL AUDIO %d \n", length  );  


for (int i = 0; i < length-1; i++) 
{

    if (audio_samples[i] > threshold  && run) 
    {

        // ** is this realloc working ?
        // event_flags = (int*)realloc(event_flags, sizeof(int) * (flag+1));
        *event_flags = (int*)realloc(*event_flags, sizeof(int)*(flag+1)); // reallocate the size of the array
        *event_flags[flag] = i;
        // printf("FLAG CREATED! %i\n ", i);
        printf("EVENT FLAG %i  %i\n",flag, *event_flags[flag] );
        if (flag >5) {
            printf("%d\n", i);
        }

        flag++;
        run = false;




    }   

    if (!run) {
        counter++;
        if (counter > 20100) { // hardcode minimum size for now. 
            counter = 0;
            run=true;
        }
    }

}

printf("\n\n\n NUMBER OF EVENTS --- %d\n", flag);

for (int i = 0; i < flag; i++) {
    printf("FLAG %i  -- %d\n", i, *event_flags[i]);
}



printf("\nFIVE samples before and after my second flag: \n 0 should indicate a reach in the threshold\n");

for (int i = 0; i <10 ; i++) {
    printf("VOCAL SAMPLE %i  %i \n", i-5,audio_samples[*event_flags[1]+i-5] );
}


return flag;
 }

【问题讨论】:

  • 你能显示你malloc数组的代码位置吗?
  • 你能显示event_flags的定义吗?我假设int **event_flags,但想检查一下。

标签: c arrays loops memory-management


【解决方案1】:

首先,您不应该将realloc 的返回值强制返回。

那么如果我假设那个变量的类型是int*

*event_flags[flag] = i;

*多了一个不?

编辑:在您对排除演员表的评论之后。

因此,如果您的event_flags 实际上是int**,那么您就真的走错了方向。看到你的使用,我猜你只是想要一个 int 的数组。如果你这样做,然后

event_flags[flag] = i;

到处都没有*,你的问题应该会消失。

如果你真的需要这种间接方式,你不仅要分配数组event_flags,还要分配这些指针指向的所有单独的数组,比如

for (size_t j = startvalue; j < something; ++j)
   event_flags[j] = malloc(whatever);

【讨论】:

  • 嗯.. 不完全确定您的意思?我应该完全摆脱演员阵容吗?
  • 是的。 C 中的强制转换几乎总是表明代码不正确。也就是说,如果您的代码在没有强制转换的情况下无法编译或发出警告,那么您可能做错了什么。如果它在没有演员表的情况下工作,请删除演员表,这样它就不会向阅读代码的人暗示你正在执行丑陋的黑客攻击。
  • 我已经摆脱了演员阵容,但随后得到“从 void* 到 int** 的无效转换”。有什么帮助吗?
【解决方案2】:

我认为您可能对* 运算符与[] 运算符的优先级有问题。即*event_flags[flag](*event_flags)[flag] 不引用相同的内存位置。第一个对应**(event_flags + flag)(可能无法访问),而第二个对应*((*event_flags) + flag)(你想要的)。

因此,您应该将代码重写为:

int** event_flags;
// ...
*event_flags = realloc(*event_flags, sizeof(int) * (flag + 1));
(*event_flags)[flag] = i;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-26
    • 1970-01-01
    • 2016-07-03
    • 2019-03-21
    • 2013-06-01
    相关资源
    最近更新 更多