3

My question, now reduced to a - hopefully - minimal example, is why the following code segfaults.

It can of course be seen as a duplicate of the proposed question, provided you have found the latter. The problem is, I failed to find the question in my initial search and so may many newbies, not knowing the cause of error. I propose this as a duplicate I could have found:

Segmentation Fault before main

but the problem description is very long, so that I believe my minimised and much shorter code might be better for illustrating the problem. In any case, it is a duplicate. I propose the moderators set this as a duplicate and set a link from the second possible duplicate to the first one.

#include <stdio.h>


/* Parameters */
#define N 3072  
#define LDA N

/* Main program */
int main()  {
        printf( "-----------------------------------------------> Entry main.\n" );
        /* Local arrays */
    double a[LDA*N];
        printf( "-----------------------------------------------> End main.\n" );
return 0;        
}

A segfault does not occur when

#define N 3072

is replaced by

#define N 5

Neither does a segfault occur when the line

double a[LDA*N];

is omitted.

I am especially confused by the observation that the segfault occurs without reaching

printf( "-----------------------------------------------> Entry main.\n" );

which I put directly at the beginning of main.

For completeness, I run the code like this:

ludi@ludi-M17xR4:~/Desktop/tests$ g++ -o minicombo.x minicombo.cc && ./minicombo.x
Community
  • 1
  • 1
Ludi
  • 451
  • 4
  • 17
  • 3
    `std::ifstream` This is **NOT** C – Eregrith Jul 06 '15 at 14:33
  • @Eregrith Indeed... Thank you! – Ludi Jul 06 '15 at 14:35
  • 1
    If you want to debug with output, use `std::cerr` (or `fprintf(stderr,...` if you must). – Baum mit Augen Jul 06 '15 at 14:42
  • 1
    Since you have not given us `dsyev`, we cannot reproduce the error. If you prepare a [minimal complete example](http://stackoverflow.com/help/mcve) the cause of the error will become clear. To begin with, if you believe that the segfault occurs before control reaches the first line of `main()`, then try removing all the other lines of `main()` and see what happens. – Beta Jul 06 '15 at 14:44
  • @BaummitAugen Apologies. I do not know them. I will go and learn about them immediately. Thank you. – Ludi Jul 06 '15 at 14:45
  • @Beta Thank you! I shall do so immediately after reading about std::cerr. – Ludi Jul 06 '15 at 14:47
  • 1
    You immediately segfault because `double a[LDA*N];` inside `main()` creates a 72MB array which is simply too large for automatic storage. – Blastfurnace Jul 06 '15 at 14:53
  • @Blastfurnace Thanks a lot. Could you say something on how to do it correctly? I am a noob... – Ludi Jul 06 '15 at 15:02
  • @Ludi Save data in an [`std::vector`](http://en.cppreference.com/w/cpp/container/vector). Do *not* start to use `new[]`. (If the size of the collection is small and known at compile time, you also can use `std::array`.) – Baum mit Augen Jul 06 '15 at 15:04
  • Now this question is no longer off-topic, but a duplicate of http://stackoverflow.com/questions/1847789/segmentation-fault-on-large-array-sizes (but I think I cannot vtc the same question twice), (Well, minus the printf part, but I'm sure there's a dupe for that too) – Baum mit Augen Jul 06 '15 at 17:01

1 Answers1

5

The segfault is likely due to the array definition double a[LDA*N];. This creates a 72MB array with automatic storage duration ("on the stack"). You have several alternatives.

  1. Use std::vector<double> created with the desired size or resize() member function.
  2. Dynamic allocation with std::unique_ptr<double[]> or new[]/delete[]. Beware, manual memory management is fraught with peril.
  3. Make the array static or global.
Blastfurnace
  • 18,411
  • 56
  • 55
  • 70
  • I don't think it is a good idea to teach beginners `new[]` and `delete[]`. And certainly do not use `malloc` in C++! Also: Lulz, the gif in your profile page. :) – Baum mit Augen Jul 06 '15 at 15:09
  • 1
    @BaummitAugen: Good point, I added some scary words to my answer. – Blastfurnace Jul 06 '15 at 15:12
  • 1
    I think this answer is right, since I followed the suggestion of beta and removed anything inside main(). There was no segfault. Then I added lines one by one and the programme segfaulted right when I added double a[LDA*N]; Should I rewrite the question with a minimal example now? – Ludi Jul 06 '15 at 15:12
  • I think the `malloc`/`free` part needs to be *much* scarier, or better removed. Using `malloc` in C++ is *really* not a good idea. – Baum mit Augen Jul 06 '15 at 15:20
  • @BaummitAugen: While I would never use it or allow it in a code review, `malloc` is a possible solution with primitive types. I'm just trying to enumerate all options (added strikethrough to answer for more discouragement). – Blastfurnace Jul 06 '15 at 15:26
  • @Blastfurnace I think this answer is ok as it stands now. But if you really wanted to enumerate all options, you forgot e.g. `std::dequeu`, `std::valarray`, dynamically allocated `std::array`... Of course all of them are not appropriate here, what I try to say is that one should probably focus on all *reasonable* solutions, which in this case, `malloc` certainly is not (nor any of the other non `std::vector` alternatives IMO, but one could argue about that). – Baum mit Augen Jul 06 '15 at 15:38
  • 1
    @BaummitAugen: You've convinced me, change made and your canned chicken is in the mail. – Blastfurnace Jul 06 '15 at 15:43
  • @Blastfurnace Why does it not execute the invocations of printf that come before the definition of the array? – Ludi Jul 06 '15 at 16:35
  • 2
    @Ludi: My guess is that space for local variables (including those arrays) is set aside when the function scope is entered. I don't believe the language requires the `printf` execute before the array comes into existence even though the function call appears before the array definition. Of course the segfault could also be preventing any buffered output from appearing, it is a catastrophic event. – Blastfurnace Jul 06 '15 at 16:55