Detonar
Detonar

Reputation: 1429

Segmentation fault while function call

I got a struct Chat

struct Chat
{
    int m_FD;
    int m_BindPort;
    char m_NameLength;
    char* m_Name;
    char m_PeerCount;
    char** m_PeerList;

} typedef Chat_t;

i'm initializing it with this function:

int chat_init(Chat_t* this, unsigned int nameLen, char* name, unsigned short int bindPort, unsigned int peerCount, char** peerList)
{
    this->m_NameLength = nameLen;
    this->m_Name = malloc(sizeof(char) * (nameLen+1));
    strcpy(this->m_Name, name);
    this->m_BindPort = bindPort;
    this->m_PeerCount = peerCount;
    this->m_PeerList = malloc(sizeof(char*) * peerCount);
    for(int i=0; i<peerCount; i++)
    {
        this->m_PeerList[i] = malloc(sizeof(char) * 16); // enough for xxx.xxx.xxx.xxx\0
        strcpy(this->m_PeerList[i], peerList[i]);
    }

    //Socket initialization for TCP connection...
    //Commenting this out doesn't change anything so i'm hiding it for simplification

    return 0;

}

After that i'm calling a second function

int chat_communicate(Chat_t* this)
{
    printf("2\n");
    fflush(stdout);

    //Some stuff that doesn't matter because it isn't even called

    return retVar;
}

in main like this

void main(void)
{
    char* peerList[1];
    char username[USERNAME_MAX_LEN];
    int initRet;
    int loopRet;
    Chat_t chat;

    peerList[0] = "192.168.2.2";

    memset(username, 0, USERNAME_MAX_LEN);

    printf("Please enter your user name: ");
    scanf("%s", username);

    username[USERNAME_MAX_LEN-1] = 0;

    initRet = chat_init(&chat, strlen(username), username, 1234, 1, peerList);

    printf("File Descriptor: %d\n", chat.m_FD);
    printf("Binding Port: %d\n", chat.m_BindPort);
    printf("Name Length: %d\n", chat.m_NameLength);
    printf("Name: %s\n", chat.m_Name);
    printf("Peer Count: %d\n", chat.m_PeerCount);
    for(int i=0; i< chat.m_PeerCount; i++)
    {
      printf("Peer[%d]: %s\n", i, chat.m_PeerList[i]);
    }

    printf("1");
    ret = chat_communicate(&chat);

    //Even more Stuff that isn't even called

}

My program outputs the following

File Descriptor: 3
Binding Port: 1234
Name Length: 4
Name: User
Peer Count: 1
Peer[0]: 192.168.2.2
1
Segmentation Fault

It compiles without errors or even warnings.

You can also assume that every string is null-Terminated The stuff i replaced with comments itn't that complicated but just too much to show.

Every value inside the struct is printed with printf right before but when passing this very struct per reference the application crashes.

What i want to know is why i'm getting this Segmentation Fault. Since it appeared while calling a function i thought it is some kind of layout problem but i havn't find anything like that.

Addition: Because some people weren't able to believe me that the code i hid behind "some stuff" comments doesn't change anything i want to state this here once again. This code just contains a tcp socket communication and only performs read-operations. I also am able to reproduce the error mentioned above without this code so please don't get stuck with it. Parts does not influence the object under observation at all.

Upvotes: 0

Views: 176

Answers (4)

Mohammad Azim
Mohammad Azim

Reputation: 2943

Why don't you debug it yourself. If using GCC, compile your code with options -g -O0. Then run it with gdb:

gdb ./a.out
...
(gdb) r

If it crashes do:

(gdb) bt

This will give exactly where it crashes.

Update: There may be potential problems with your code as found by other users. However, memory allocation related issues will not crash your application just on calling function chat_communicate. There could be different reasons for this behaviour ranging from stack overflow to improper compilation. Without seeing the whole code it is very difficult to tell. Best advice is to consider review comments by other users and debug it yourself.

Upvotes: 1

Jabberwocky
Jabberwocky

Reputation: 50831

Now that you have posted an almost complete code, I was able to spot two problems next to each other:

    int chat_init(Chat_t* this, unsigned int nameLen, char* name, unsigned short int bindPort, unsigned int peerCount, char** peerList)
    {
      this->m_NameLength = nameLen;

      this->m_Name = malloc(sizeof(char) * (nameLen + 1)); // correct
  //< this->m_Name = malloc(sizeof(char) * nameLen);       // wrong

      strcpy(this->m_Name, name);                          // correct
  //< memcpy(this->m_Name, name, nameLen);                 // wrong
      ...

The lines starting with //< is your original code:

Here you don't allocate enough space, you need to account for the NUL terminator:

this->m_Name = malloc(sizeof(char) * nameLen);

And here you don't copy the NUL terminator:

memcpy(this->m_Name, name, nameLen);

You really need to be aware how strings work in C.

Upvotes: 2

Andrew Henle
Andrew Henle

Reputation: 1

Among other potential problems,

this->m_PeerList = malloc(sizeof(char)*peerCount);

is clearly wrong.

m_PeerList is a char **, yet you're only allocating peerCount bytes, which only works if a char * pointer is one byte on your system - not likely.

Replace it with something like

this->m_PeerList = malloc(peerCount * sizeof( *( this->m_peerList ) ) );

Note that sizeof( char ) is always one - by definition.

Upvotes: 3

Peter K.
Peter K.

Reputation: 8108

You're not allocating enough memory for the this->m_Name. It should be on more than this if you want it to store the null-terminated string of the name.

That, or we need more information about the peerList.

Upvotes: 2

Related Questions