【问题标题】:c++ : Defining array within an if-else condition erases after it exitsc++:在 if-else 条件中定义数组在退出后会被擦除
【发布时间】:2020-12-03 20:53:42
【问题描述】:

我有一个脚本可以填充数组,可以使用函数,也可以不使用。

它接受一个参数readmode,它决定是否使用该函数;和一个参数len_arr,它决定了数组的长度。

我简化了代码,以便每次迭代数组长度都会增加每次迭代,但在实际情况下,每次迭代我都会加载不同长度的音频文件,因此我使用 malloc 来初始化,然后我释放它一次已完成后处理。

主脚本

// imports
  #include <iostream>     /* cout */
  #include <stdio.h>      /* printf */
  #include <stdlib.h>     /* atoi */
  using namespace std;

  void function_1(int len_arr, double * output_buffer){
    for (int j=0; j<len_arr; ++j){
      output_buffer[j] = 1.0*j;
    }
  }


int main (int argc, char ** argv) {
  int readmode = atoi(argv[1]);

  // double *buffer;
  // cout << "1 : Memory Address of buffer="<<buffer << endl;

  for (int len_arr=1; len_arr<=5; ++len_arr){

    if (readmode==1){
      double *buffer = (double *)malloc(len_arr * sizeof(double));
      function_1(len_arr, (double*)buffer);
      cout << "\n2 : Memory Address of buffer="<<buffer << endl;
      printf("readmode=1 : buffer[:5]=[%f %f %f %f %f]\n", buffer[0],buffer[1],buffer[2],buffer[3],buffer[4]);

    } else if (readmode==2){
      double *buffer = (double *)malloc(len_arr * sizeof(double));
      for (int j=0; j<len_arr; ++j){
        buffer[j] = 1.0*j;
      }
      cout << "\n3 : Memory Address of buffer="<<buffer << endl;
      printf("readmode=2 : buffer[:5]=[%f %f %f %f %f]\n", buffer[0],buffer[1],buffer[2],buffer[3],buffer[4]);
      
    }

  /* Do my post-processing with buffer */

  // verbose
    cout << "\n4 : Memory Address of buffer="<<buffer << endl;
    printf("readmode=%i : buffer[:5]=[%f %f %f %f %f]\n", readmode, buffer[0],buffer[1],buffer[2],buffer[3],buffer[4]);
    free(buffer);

  }
  return 0 ;
}

我是这样编译的

g++ -o ./debug_ifelse.out -Ofast -Wall -Wextra -std=c++11 "./debug_ifelse.cpp"

以下是我面临的问题:

  1. 如果我在输入 if-else 之前没有初始化 double *buffer,我会收到编译错误,即它没有被声明,即使我确实在每个条件中定义了它。
./debug_ifelse.cpp: In function ‘int main(int, char**)’:
./debug_ifelse.cpp:41:48: error: ‘buffer’ was not declared in this scope
     cout << "\n4 : Memory Address of buffer="<<buffer << endl;
                                                ^
./debug_ifelse.cpp: At global scope:
./debug_ifelse.cpp:14:15: warning: unused parameter ‘argc’ [-Wunused-parameter]
 int main (int argc, char ** argv) {
               ^
  1. 当我初始化它时(虽然我没有看到它的含义),if-else 外部和内部的变量double *buffer 似乎位于不同的内存地址中,我无法访问在 if 中定义的那个-else。
1 : Memory Address of buffer=0

2 : Memory Address of buffer=0x24f3030
readmode=1 : buffer[:5]=[0.000000 0.000000 0.000000 0.000000 0.000000]

4 : Memory Address of buffer=0
Segmentation fault

【问题讨论】:

  • 我不认为你在这里粘贴的代码会编译。
  • 提示:在 C++ 中使用 std::vector 并尽可能远离 C 数组和指针。您可以只使用push_back 而不是所有这些重新分配代码。
  • @tadman 我使用数组的原因是因为我将缓冲区作为音频文件读取,正如我的问题第 3 段所述,使用 sf_read_double (infile, buffer); 将音频加载到数组。我简化了对音频文件的读取,只需用function_1 填充它。但问题的主要目的是解决为什么在我退出 if-else 条件后,我的缓冲区无法使用。
  • 您在 if 范围内声明了内容,因此在此范围之外无法访问。您需要在分支代码之前声明指针。
  • 您还可以创建一个任意大小的向量,并像缓冲区一样使用它,就好像它只是一个指针一样写入它,这大大简化了内存管理。

标签: c++ arrays if-statement memory-management


【解决方案1】:

取消注释 // 双 *buffer;缓冲区应该在上面定义for循环。

double *buffer;

在 if-else 块中只使用缓冲区而不定义它。

buffer = (double *)malloc(len_arr * sizeof(double));

【讨论】:

    【解决方案2】:

    读取错误:

    ./debug_ifelse.cpp: In function ‘int main(int, char**)’:
    ./debug_ifelse.cpp:41:48: error: ‘buffer’ was not declared in this scope
         cout << "\n4 : Memory Address of buffer="<<buffer << endl;
    

    查看第 41 行 - 您使用了变量 buffer,因此如果它在第 40 行被注释掉,那么它就不会在范围内声明 - 就像错误所说的那样。

    请注意,如果您确实在第 40 行声明它,那么就在这一行。

    double *buffer = (double *)malloc(len_arr * sizeof(double));
    

    创建另一个(不同的)同名变量,这可能不是您想要的。让它buffer = (double *)malloc(len_arr * sizeof(double));

    请注意,您在第 40 行确实需要 buffer,因为在所有循环之后,您需要 free(buffer),因此在该范围内需要它。

    旁注:

    • 因为你的循环一直在说buffer = malloc(... 你在泄漏 记忆
    • 如果您使用 C++,为什么使用 malloc/free 而不是 new/delete?

    【讨论】:

    • 所以我不明白这个错误,我在 if 条件下在double *buffer = (double *)malloc(len_arr * sizeof(double)); 中明确定义了缓冲区,为什么它说没有声明?
    • 我会尝试新建/删除,谢谢您的建议!我是 C++ 新手,所以我想我正在使用过时教程中的过时方法
    猜你喜欢
    • 2013-11-12
    • 2020-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-18
    相关资源
    最近更新 更多