【问题标题】:Passing pointer variables through functions in C通过 C 中的函数传递指针变量
【发布时间】:2011-07-12 16:30:45
【问题描述】:

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

我是这样开始的:

   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;

    }   

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

【问题讨论】:

  • 能否包含打印意外值的代码和写入event_flags 数组的代码?没有它,很难看出你做错了什么。就目前而言,您不会初始化您分配的数据,因此它可能包含随机垃圾。
  • 这不应该发生。它实际上只是 apply_threshold 的返回破坏了它 - 即两个打印之间没有其他操作?然后,您可能通过溢出其他地方的缓冲区而意外损坏了 event_extractor 堆栈帧中 event_flags 的值。什么操作系统/编译器 - 你可以运行 valgrind 吗?
  • 我们真的需要看看你是如何在每个函数中引用 int 指针的,否则你只是在传递一个指针。
  • 我相信我已经发布了所有相关的代码。如果需要更多说明,请告诉我。

标签: c arrays pointers argument-passing


【解决方案1】:

您是否在 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:针对新问题。

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

【讨论】:

  • @Erik。我相信我正在重新分配,但我可能做错了。
  • @Eric Brotto:您正在重新分配。查看我的示例,apply_threshold 应该使用 int **event_flags,使用 *event_flags,并且应该使用 &amp;event_flags 调用函数。
  • @Erik。这似乎有效。但是现在在我得到的 realloc 之后的循环中:程序接收到的信号:“EXC_BAD_ACCESS”。此帧内部的前一帧(gdb 无法展开超过此帧)。有什么想法吗?
  • @Eric Brotto,我认为你的问题是 realloc 可能“在同一个地方增加内存”或“在复制后给你一个更大的块”如果第二个发生你的代码赢了不行,如果第一次发生,它会的。
  • @Eric Brotto:更新您当前的代码,或提出新问题
【解决方案2】:

您需要传递指向指针的指针或指向指针的引用。 realloc 可能会将您的内存移动到另一个位置,而调用者不会注意到。

  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()。 如果指向的区域被移动,则执行 free(ptr)

【讨论】:

  • 您能否更具体地说明我应该如何解决这个问题?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-24
  • 2021-06-24
  • 1970-01-01
  • 1970-01-01
  • 2019-09-16
  • 1970-01-01
相关资源
最近更新 更多