1
votes

Hello I need help understanding sprintf and C character arrays. I am coming from a Java background and understand C up to pointers(I've been teaching myself C :/).

Anyways I'm getting a segfault error when using sprintf and needed a couple questions answered. 1)Does sprintf overwrite other elements in the character array? If so shouldn't setting the first element to 0 fix it?

2) Would a char array running out of room to place elements qualify as a segfault?

char buffer[15];
char dbuff[15];
char* numer;//these variables don't cause the problem, 
// but just thought I'd include them
char* denom;
char** num_ptr = &numer;
char** denom_ptr = &denom;
for(j=1; j < nR; j++)
{
    for(i=1;i < nC; i++)
    {
        sprintf(buffer,"%i",sorts[j][i]);  //problems after 1 loop
        printf("buffer %s",buffer); 
        sprintf(dbuff,"%f",srcMat[j][i]);
        // a new incoming rank
        if(g_hash_table_lookup(rankCnt,buffer) == NULL)
        {
            avgholder[k++] = sorts[j][i];

            printf("%i kkkk      %i sorts\n",k,sorts[j][i]);

            g_hash_table_insert(rankAvg,buffer,dbuff); //problem occurs here
            g_hash_table_insert(rankCnt,buffer, (void*)1);
        }
    }

What I've tried: adding buffer/dbuff[0]=0, memset, and a couple other methods but I forget :(. I think I need to allocate memory but I've never done so, will that work? Also what I'm basically doing is reading in a file that is a 2d matrix, I sorted it into sorts, and am using glib's hashmap to map them to do matrix manipulations. Any help would be great!

Program received signal SIGSEGV, Segmentation fault. 0x0023af03 in ?? () from /lib/i386-linux-gnu/libc.so.6

(gdb) backtrace

0x0023af03 in ?? () from /lib/i386-linux-gnu/libc.so.6

0x00238850 in strtod () from /lib/i386-linux-gnu/libc.so.6

0x00000000 in ?? ()

*EDIT sorry but I didn't think the array initialization was the problem. For srcMat its double srcMat[nR][nC] where nR and nC are ints that are the row and columns.

for sorts i used int sorts[nR][nC]; and from there I fill it with integer values based on ranking of the matrix column.

GHashTable* rankAvg= g_hash_table_new(g_str_hash, g_str_equal);
GHashTable* rankCnt = g_hash_table_new(g_str_hash, g_str_equal);

Thanks for helping guys.

Also the reason I start at 1 as opposed to 0 is that the input matrix file contains a header line and header columns, two things not needed for my matrix quantile normalization.

Also slightly off topic but a general question, I'm having trouble casting gpointers back into doubles(I can cast into ints), so right now I'm just storing the elements as strings and just atof(double) when I need them. Any thoughts on that?

EDIT #2 Sorry guys but I just narrowed down the problem actually the problem is occuring on the ghashtable insert method, I get through 1 loop iteration and on the second the insert causes a segfault.

3
how is this sorts[][] array declared? same for srcMat[][]Vinicius Kamakura
You haven't shown the definition of sorts. And you haven't shown us how you've initialized buffer. (Note that in C, primitive types are not automatically initialized to zero, unless they are global or static).Oliver Charlesworth
@Oli the buffer initialization doesn't matter since he sprintf's to it.Vinicius Kamakura
@hexa: Ah, yes, I didn't spot that it's an argument to the first sprintf!Oliver Charlesworth

3 Answers

1
votes

Running out of room in the array certainly could make a segfault -- depending on where the array is in memory. But notice what your array bounds are: you've going from 1 to nR-1 or nC-1. C has 0-based arrays. Are you sure you're doing what you want there?

1
votes

In C, arrays indexes start with 0, not with 1. Try initializing i and j in the for loops with 0, you are probably accessing the wrong memory, therefore the seg fault.

EDIT Well if you initialize it with 1 on purpose, you should loop to nR-1 and nC-1 then, so you don't access the wrong memory.

EDIT2

This line looks VERY suspicious:

g_hash_table_insert(rankCnt,buffer, (void*)1);

try declaring an int somewhere, giving it the value of 1 and passing it as a parameter. If it is an int that you should be passing... how is this function's call signature?

int myint = 1;
g_hash_table_insert(rankCnt,buffer, &myint);
1
votes

I'm afraid there's some bug in the lib... I have also encountered some weird segmentation error in some particular Gtk+ program -- I've no idea what is the point as I failed to return the error in my tests. However, in my case, the segmentation error occurs after I malloc 24*64 bytes of memory size, where 24 is the size of a structure, which is not the point -- the point is the error only occurs when it is 64 -- it works fine with all the other values -- there's no reason how 64 could be the only exception!

As gdb traces the error back to /lib/i386-linux-gnu/libc.so.6, the same source as in your question -- though they probably have different causes -- it is why I've found your question here -- I really don't think it is because of my codes nor yours.