2

I am trying to check if a map is empty or not in c++ using a pointer to a map. However, I get a segmentation fault, although the map is not NULL. The code is so simple and here:

void func(std::map<std::string, std::vector<Foo*> >* myMap){
   if(myMap == NULL)
      std::cout << "My map is Null" << std::endl;
   else if(myMap->empty())
      std::cout << "My map is empty" << std::endl;
}

The parameter sometimes may be an uninitialized map. When I executed this code, the result is a segmentation fault. The code skips the if statement, because it does not see myMap as a NULL map. Then, it crashes in myMap->empty() command. It also crashes when I try to call any function of the map, such as clear, begin, size, etc. So, if myMap is not NULL, what kind of reason could it cause to this seg. fault?

Jorge López
  • 68
  • 1
  • 9
simon_tulia
  • 396
  • 1
  • 6
  • 22
  • 1
    Show the code where map initialization happens. – lisyarus Mar 05 '15 at 13:17
  • The problem is not within this function. Look [here](http://ideone.com/rZZRdT) – mkaes Mar 05 '15 at 13:19
  • A pointer can be invalid without being null; perhaps that's the case. Perhaps the map has been destroyed, leaving the pointer dangling. Or perhaps memory corruption has broken the map. These things are easy to do if you juggle unmanaged pointers like this. Why are you using so many pointers in the first place? – Mike Seymour Mar 05 '15 at 13:19
  • run it under valgrind, most likely you are receiving garbage pointer – bobah Mar 05 '15 at 13:19
  • "I am trying to check if a map is empty" - that's what `std::map::empty()` is for, but you seem to rather want to know how to test is a pointer is `nullptr` which is something else. – Jesper Juhl Feb 15 '23 at 17:52

3 Answers3

4

Pointers are not set to NULL by default, so the caller might use junk information as the parameter. The following usage example will crash:

std::map<std::string, std::vector<Foo*> >* m;
func(m);

This will compile, but will crash as m point to some garbage. Setting pointers with null is safer:

std::map<std::string, std::vector<Foo*> >* m = NULL;
func(m);

and will work as planned.

I suggest that you pass argument by value or by reference but not by pointer (remove the *):

void func(std::map<std::string, std::vector<Foo*> > myMap){
G. Ko
  • 403
  • 6
  • 15
1

More code is needed to say for sure, but if myMap is not zero it probably points to a 'wrong' location (not a map you initialised)

Maybe you took the address of a stack based map that no longer exists? Without more code I can only guess.

Pieter
  • 17,435
  • 8
  • 50
  • 89
0

It segfaults because you always need to initialize your pointers to use them, even to compare them with nullptr. See for instance, https://stackoverflow.com/a/32211682/2201117:

Take an uninitialized pointer:

int* ptr;//points to any location in memory

Take a null pointer:

int* ptr = NULL;//normally points to 0x0 (0)

Both would cause undefined behaviour if dereferenced. NULL is often defined as 0.

So, in your example, there is nothing wrong with your function, but there's a problem with the pointer you are using:

std::map<std::string, std::vector<Foo*> >* m = NULL;
func(m); // ok, prints "My map is Null"

You should also check the difference between NULL and nullptr if working in any modern C++ implementation (What exactly is nullptr?).

Jorge López
  • 68
  • 1
  • 9