简体   繁体   English

尝试从动态分配的二维数组 c++ 中读取值并给出 munmap_chunk() 时出现分段错误:尝试删除它时

[英]segmentation fault when trying to read values from dynamically allocated 2-D array c++ and gives munmap_chunk(): when trying to delete it

I'm trying to measure the time taken for insertion sort (avg, best, and worst for certain a size, n times) and storing all results in a 2D array我正在尝试测量插入排序所花费的时间(对于某个大小,平均、最佳和最差, n次)并将所有结果存储在二维数组中

Here is the code for it:这是它的代码:

#include <iostream>
#include <sys/time.h>

void insertionSort(int* array, int size) {
   for (int i = 1; i < size; i++) {
    std::cout << "insetion flag " << i  << std::endl;
    int key = array[i];
    int j = i - 1;
    while (key < array[j] && j >= 0) {
        array[j + 1] = array[j];
        j--;
    }
    array[j + 1] = key;
  }
}

void getRandomArray(int* avg, int* best, int* worst, int size) {
srand((unsigned)time(0));
    for (int i = 0; i < size; i++) {
      //std::cout << "rand flag " << i  << std::endl;
      avg[i] = (rand() % 100) + 1;
    }
    for (int i = 0; i < size; i++) {
        //std::cout << "copy flag " << i  << std::endl;
        best[i] = avg[i];
    }
    insertionSort(best, size);
    for (int i = 0, j = size; i < size; i++, j--) {
        //std::cout << "rev flag " << i  << std::endl;
        worst[j] = best[i];
     }
 }

 double getComplx(int* arry, int size) {
      struct timeval *start, *end;

      std::cout << "comp flag " << std::endl;

      gettimeofday(start, NULL);
      insertionSort(arry, size);
      gettimeofday(end, NULL);

      double timeTaken = (end->tv_sec - start->tv_sec) * 1000000 + (end->tv_usec - start->tv_usec);
      return timeTaken;
  }

  int main(int argc, char** argv) {
      int size = atoi(argv[1]);
      int times = atoi(argv[2]);
      int* avg   = new int[size];
      int* best  = new int[size];
      int* worst = new int[size];

      double** resTable = new double*[times];
      for (int i = 0; i < times; i++) {
          std::cout << i << std::endl;
          resTable[i] = new double[3];
      }

      std::cout << "flag 1" << std::endl;
      for (int i = 0; i < times; i++) {
          getRandomArray(avg, best, worst, size);

          std::cout << "flag 2" << std::endl;
          resTable[i][0] = getComplx(avg, size);
          std::cout << " avg ("<<i<<") (0) " << resTable[i][0] << std::endl;
          resTable[i][1] = getComplx(best, size);
          std::cout << " best ("<<i<<") (0) " << resTable[i][1] << std::endl;
          resTable[i][2] = getComplx(worst, size);
          std::cout << " worst ("<<i<<") (0) " << resTable[i][2] << std::endl;
          printf("|%9.0f  |%9.0f  |%9.0f  |", resTable[i][0], resTable[i][1], resTable[i][2]);
          std::cout << " : loop no : " << i << std::endl;
     }

    std::cout << "after loop" << std::endl;

    delete []avg;
    std::cout << "after avg" << std::endl;
    delete []best;
    std::cout << "after best" << std::endl;
    delete []worst;
    std::cout << "after worst" << std::endl;
    for (int i = 0; i < times; i++) {
      std::cout << "after " << i << std::endl;
      delete[] resTable[i];
   }
   delete []resTable;
   std::cout << "last flag" << std::endl;
   return 0;
}

In the main function I have a dynamically created array and store all data in it but it gives a segmentation fault when it reaches in last row to store data.在主函数中,我有一个动态创建的数组并将所有数据存储在其中,但是当它到达最后一行存储数据时会出现分段错误。

So I tried to skip storing in last row and it worked but this time when deleting at the end it again gives me the error "munmap_chunk() : invalid pointer"所以我试图跳过存储在最后一行并且它起作用了但是这次在最后删除时它再次给我错误“munmap_chunk():无效指针”

I have checked other questions related to this but couldn't find what I am doing wrong here.我已经检查了与此相关的其他问题,但在这里找不到我做错了什么。

I know we can do it better with vectors but I am just trying to get a better understanding of the inner workings of pointers and memory allocation.我知道我们可以用向量做得更好,但我只是想更好地了解指针和内存分配的内部工作原理。

You've got two instances of reading/writing outside of allocated memory bounds, and two instances of using an uninitialized pointer.您有两个在分配的内存范围之外读/写的实例,以及两个使用未初始化指针的实例。

First, in insersionSort :首先,在insersionSort

while (key < array[j] && j >= 0) {

You use j to index the array before checking if the value is positive.在检查值是否为正之前,您可以使用j来索引数组。 This results in reading before the start of the array.这导致在数组开始之前读取。 You want to check j first:你想先检查j

while ( j >= 0 && key < array[j]) {

Then you have this in getRandomArray:然后你在 getRandomArray 中有这个:

for (int i = 0, j = size; i < size; i++, j--) {

You start j at size , then use it to index the array.你从j开始size ,然后用它来索引数组。 This writes past the end of the array.这将写入数组的末尾。 You want to start one element earlier:你想提前开始一个元素:

for (int i = 0, j = size - 1; i < size; i++, j--) {

Finally, there's getComplx :最后,还有getComplx

 double getComplx(int* arry, int size) {
      struct timeval *start, *end;

      std::cout << "comp flag " << std::endl;

      gettimeofday(start, NULL);
      insertionSort(arry, size);
      gettimeofday(end, NULL);

      double timeTaken = (end->tv_sec - start->tv_sec) * 1000000 + (end->tv_usec - start->tv_usec);
      return timeTaken;
  }

The gettimeofday function expects a pointer to a struct timeval , but in both cases you pass it an uninitialized pointer. gettimeofday函数需要一个指向struct timeval的指针,但在这两种情况下,您都将一个未初始化的指针传递给它。 Rather than making start and end pointers, make them instances of struct timeval and pass their addresses:与其制作startend指针,不如让它们成为struct timeval实例并传递它们的地址:

 double getComplx(int* arry, int size) {
      struct timeval start, end;

      std::cout << "comp flag " << std::endl;

      gettimeofday(&start, NULL);
      insertionSort(arry, size);
      gettimeofday(&end, NULL);

      // also change -> to .
      double timeTaken = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec);
      return timeTaken;
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM