DEV Community

Discussion on: I'm an Expert in Memory Management & Segfaults, Ask Me Anything!

 
codemouse92 profile image
Jason C. McDonald • Edited

I think I found it. The problem is in main.cpp:

    size_t smLength = sizeof(*sm);
    size_t* smlen;
    smlen = (size_t*) smLength;
    sig.signMessage(sm, smlen, m, mlen);
Enter fullscreen mode Exit fullscreen mode

There are two problems here.

  1. sizeof(*sm) gives you the length of the value pointed to by sm. This will not give you the length of the string, but rather the size of the first item in the string/array, being a character. In other words, the value here is 1, regardless of how long the string starting at pointer sm actually is. I'll come back to this.

  2. Even if smLength were correct, (size_t*) smLength; is not going to give you the address to smLength for storing in the pointer. Instead, this is casting, or reinterpreting, the value, the integer 1 in this case, as a pointer. But what's at pointer 0x00000001? Who knows. This is known as a wild pointer.

If you look throughout your code, you'll see these same mistakes occur other times, such as with mlen.

Don't take this as a criticism, but I'm dubious about where you learned to use pointers. This is pretty much a royal hash. If you learned this from an online tutorial, example, or article, I'd strongly recommend avoiding it in the future. (Check to make sure you didn't just misunderstand first.)

The reason for the segfault is that wild pointer in #2. It's looking in the wrong place for a value, and it isn't finding it. You're lucky it failed with a segfault; it could have read in literally anything that was stored at that address in memory, whether it was coincidentally correct, subtly wrong, or absolutely bonkers. These sorts of bugs are really unpredictable like that.

Here's the operations you're misunderstanding in this code:

Getting a Pointer

To get the address of a value, for storing in a pointer, use the & operator:

size_t myValue = 42;
size_t* ptrToMyValue = &myValue;
Enter fullscreen mode Exit fullscreen mode

Getting the length of a c-string (char array)

#include <string.h>

// All three of these are valid ways to declare a c-string
char* stringA = "Hi";
char stringB[] = "there";
char stringC[20] = "Lindenouwen";

size_t lengthA = strlen(stringA);  // 2
size_t lengthB = strlen(stringB);  // 5
size_t lengthC = strlen(stringC); // 11 (NOT 20!)
Enter fullscreen mode Exit fullscreen mode

By the way...

One more pro-tip: stop using the using namespace std; trick. It's an antipattern; in production code, it's all too easy to lose track of what-comes-from-where. Namespaces exist to reduce that confusion, but using namespace negates that namespace. Most examples use it for brevity; good production code never does.

Instead, explicitly spell out namespace each time:

#include <iostream>
#include <string>

std::string greeting = "Hello, world!";
std::cout << greeting << std::endl;
Enter fullscreen mode Exit fullscreen mode

Save yourself weeks of headaches and refactoring now. Never use using namespace again.

Thread Thread
 
lindenouwen profile image
Lindenouwen

Thanks for your help!
I think it works now :p

Thread Thread
 
codemouse92 profile image
Jason C. McDonald

Excellent!

You will want to get into the habit of always testing your code thoroughly in Valgrind and addressing everything it complains about; even memory leaks. Undefined behavior has a habit of hiding until the most inconvient and unexpected moment. Write tests for your code (you should be doing that anyway!), and then execute those tests both outside of and within Valgrind.