0

I am fairly new to C and how arrays and memory allocation works. I'm solving a very simple function right now, vector_average(), which computes the mean value between two successive array entries, i.e., the average between (i) and (i + 1). This average function is the following:

void
vector_average(double *cc, double *nc, int n)
{
//#pragma omp parallel for
  double tbeg ;
  double tend ;
  tbeg = Wtime() ;
  for (int i = 0; i < n; i++) {
    cc[i] = .5 * (nc[i] + nc[i+1]);
  }
  tend = Wtime() ;
  printf("vector_average() took %g seconds\n", tend - tbeg);
}

My goal is to set int n extremely high, to the point where it actually takes some time to complete this loop (hence, why I am tracking wall time in this code). I'm passing this function a random test function of x, f(x) = sin(x) + 1/3 * sin(3 x), denoted in this code as x_nc, in main() in the following form:

int
main(int argc, char **argv)
{
  int N = 1.E6;
  double x_nc[N+1];

  double dx = 2. * M_PI / N;
  for (int i = 0; i <= N; i++) {
    double x = i * dx;
    x_nc[i] = sin(x) + 1./3. * sin(3.*x);
  }

  double x_cc[N];
  vector_average(x_cc, x_nc, N);
}

But my problem here is that if I set int N any higher than 1.E5, it segfaults. Please provide any suggestions for how I might set N much higher. Perhaps I have to do something with malloc, but, again, I am new to all of this stuff and I'm not quite sure how I would implement this.

-CJW

Chris Wong
  • 403
  • 4
  • 11
  • 2
    `int N = 1.E6; double x_nc[N+1];` will probably break the stack as it needs about 8 MB. Please allocate dynamic memory, `malloc` as you say. – Weather Vane Mar 10 '19 at 23:24
  • Right, this is what I was thinking. But how exactly would I do this? I am not familiar with the syntax. Thank you so much!! – Chris Wong Mar 10 '19 at 23:27
  • The man pages are your friend: the VS page is [here](https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/malloc?view=vs-2017) which includes an example use of `malloc`. – Weather Vane Mar 10 '19 at 23:30
  • Thank you, I will read up on this! – Chris Wong Mar 10 '19 at 23:32
  • Possible duplicate of [Difference between array type and array allocated with malloc](https://stackoverflow.com/questions/10575544/difference-between-array-type-and-array-allocated-with-malloc) – Nate Eldredge Mar 10 '19 at 23:47

1 Answers1

1

A function only has 1M stack memory on Windows or other system. Obviously, the size of temporary variable 'x_nc' is bigger than 1M. So, you should use heap to save data of x_nc:

int
main(int argc, char **argv)
{
  int N = 1.E6;
  double* x_nc = (double*)malloc(sizeof(dounble)*(N+1));

  double dx = 2. * M_PI / N;
  for (int i = 0; i <= N; i++) {
    double x = i * dx;
    x_nc[i] = sin(x) + 1./3. * sin(3.*x);
  }

  double* x_cc = (double*)malloc(sizeof(double)*N);
  vector_average(x_cc, x_nc, N);

  free(x_nc);
  free(x_cc);

  return 0;
}
Yuanhui
  • 459
  • 5
  • 15
  • actually, now I have been able to get up to 1.E8. But when I go up to 1.E9, I get a `-woverflow` compiler warning and the program seg faults again. What is my issue now? I want to go realllllly high. – Chris Wong Mar 11 '19 at 00:17
  • Look at the size of the parameter `size_t` that `malloc` takes. If it is 32 bits, then your array is again too large. Aside, you should not be using floating point values to control arrays and their indexing. Anyway it depends on the system, my MSVC can't allocate more than about 2GB. **Always check the return value from `malloc`**. If it is `NULL` the allocation failed. – Weather Vane Mar 11 '19 at 00:20