通过C中的函数传递指针变量

时间:2011-03-10 12:25:20

标签: c arrays pointers argument-passing

我在这里遇到一些奇怪的行为。任何帮助都会很棒。

我是这样开始的:

   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);


 // HERE I WOULD LIKE TO USE THE VALUES OF event_positions BUT THE ARE WEIRD I.E. THEY DON'T MATCH THE VALUES BEING PRINTED IN THE LAST METHOD. 

事件提取器然后将变量传递给另一个方法。简化如下:

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

    int number_of_flags = apply_threshold (lopass_samples, length, event_flags);
    // PRINT ARRAY event_flags HERE 
    // VALUES ARE INCORRECT AND WEIRD

}

最后一种方法:

int apply_threshold (int *audio_samples, unsigned int size_of_audio, int *event_flags)
{
// DO SOME STUFF HERE.
// PRINT THE ARRAY WHICH SHOW THE  CORRECT VALUES.



}

我希望这很清楚。基本上我有一个数组,我作为参数传递,并在方法完成后无法访问这些值。


编辑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);

第二档:

  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;

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

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

        // ** is this realloc working ?
        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] );
        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;



}

编辑2

我根据Erik的模型更新了我的代码。我的循环现在看起来像这样

    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] );
        flag++;
        run = false;

    }   

现在我收到一个看起来像这样的错误。有什么想法吗?enter image description here

2 个答案:

答案 0 :(得分:3)

您是否在apply_threshold中重新分配event_flags?如果是这样,您需要让调用者返回更新的指针。

类似的东西:

int apply_threshold (int *audio_samples, unsigned int size_of_audio, int **event_flags) {
    *event_flags = realloc ...
}

...

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

编辑:回应更新的问题:

event_flags = (int*)realloc(event_flags, sizeof(int) * (flag+1)); // reallocate the size of the array

这会更改event_flags指针的本地副本。来电者不会看到变化。使用我上面描述的方法。

EDIT2:更详细的样本。

void foo(int * v) {
    v = 0; // The local copy of main's myvar is now 0. main's actual myvar is unchanged
}

void bar(int ** v) {
    *v = 0; // Main's myvar is now 0, we have a pointer to it and can modify it.
}

int main() {
    int * myvar = (int *) malloc(1); // Allocate 1 byte and make myvar point at this byte.
    foo(myvar); // Call foo, passing a *copy of* myvar, which also points at the allocated byte
    bar(&myvar); // Call bar, passing a *pointer to* myvar, which again points to the allocated byte
}

EDIT3:回答新问题。

你的“长度”是的总数字节数吗?您将其视为整数的数量,如果它确实是字节数,则可能导致您的错误。

答案 1 :(得分:0)

您需要将指针传递给指针或指针的引用。重新分配可能会将您的记忆移动到另一个位置,呼叫者将不会注意到。

  realloc() changes the size of the memory block pointed to by ptr to size bytes.  The contents will be unchanged to the minimum of the old and new sizes; newly allocated memory will be uninitialized.  If ptr is NULL, then  the
   call  is  equivalent to malloc(size), for all values of size; if size is equal to zero, and ptr is not NULL, then the call is equivalent to free(ptr).  Unless ptr is NULL, it must have been returned by an earlier call to mal‐

loc(),calloc()或realloc()。 如果指向的区域被移动,则完成免费(ptr)