0

Hi i have the user that get randomly a number, make a structure called transaction and add it to a list. The problem is that give me back segmentation fault but i don't know where is the problem. This is a big problem cause this program is launched by another like his son, if the segmentation will not be solved the father cannot do his duty.

main:

int main(int argc, char const *argv[])
{
    id = atoi(argv[1]);
    int shmid = shmget(SH_KEY, SO_NODES_NUM * sizeof(pid_t), IPC_EXCL | 0666);
    int *nodeList = (int *)shmat(shmid, NULL, 0);

    initTransactionPool();
    struct Transaction prova1;

    while (1)
    {
        int r1 = rand() % totalBudget + 2;
        /*getBudget();
        setBudget();*/
        if (totalBudget<2)
        {
            break;
        }
        
        prova1.money = r1;
        prova1.receiver = 12;
        prova1.sender = 1;
        prova1.reward = 1;
        prova1.timestamp = "ciao";
        addTransaction(prova1);
        totalBudget-=r1;
        printf("\n il budget e' %d",totalBudget);
    }
    freeTransactionPool();
    return 0;
}

other function:

void initTransactionPool()
{
    transactionPool = (struct Transaction *)malloc(SO_TP_SIZE * sizeof(struct Transaction *));
}

void freeTransactionPool()
{
    free(transactionPool);
}

int addTransaction(struct Transaction transaction)
{
    if (sizePool >= SO_TP_SIZE - 1)
        return -1;
    ++sizePool;
    transactionPool[sizePool] = transaction;
    return 0;
}

the data: transactionPool

is saved in a ".h" like this : extern struct Transaction* transactionPool;

and in a ":c" like this: struct Transaction* transactionPool;

  • `transactionPool = (struct Transaction *)malloc(SO_TP_SIZE * sizeof(struct Transaction *));` this smells because it looks like you are allocating only space for a pointer instead of the structure. Also note that casting results of `malloc()` family is [considered as a bad practice](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). – MikeCAT Jul 21 '22 at 16:32
  • I removed the cast but the segmentation fault persit – Matteo Pagliarello Jul 21 '22 at 16:34
  • transactionPool is a pointer like this saved in a labrary "user_manager.h" : struct Transaction *transactionPool; – Matteo Pagliarello Jul 21 '22 at 16:36
  • 1
    It's not about the cast but about the size. You need `sizeof(struct Transaction)`, not a pointer – Eugene Sh. Jul 21 '22 at 16:39

1 Answers1

1

"I removed the cast but the segmentation fault persit "

The seg fault is not being caused by the cast, it is occurring because in this call:

void initTransactionPool()
{
    transactionPool = (struct Transaction *)malloc(SO_TP_SIZE * sizeof(struct Transaction *));
}  

transactionPool is allocated only the number of bytes that matches the size of a pointer on your system. (typically 4 on 32bit system or 8 for 64bit system) So, if an attempt is made to write anything to this allocated area of memory that is larger than 4 (or 8) bytes, it will optimally result in a seg-fault, clearly indicating to you that there is a problem in the code. Alternatively it could appear to do nothing, while in reality your code is brushing up against undefined behavior. (where anything can happen, even nothing for awhile, then for no apparent reason crash.)

Change it to:

struct Transaction* initTransactionPool(void)
{
    transactionPool = malloc(SO_TP_SIZE * sizeof(struct Transaction));
    return transactionPool ;//caller must check for NULL before using 
}   

or

struct Transaction* initTransactionPool(void)
{
    transactionPool = malloc(SO_TP_SIZE * sizeof(*transactionPool));
    return transactionPool;//caller must check for NULL before using 
}  

Note, added the return to allow caller to check for NULL upon return, eg:

//in calling function:
if(!initTransactionPool())
{
    //handle error
}
//continue.

About the cast...
It is removed here because although it is required if using C++, it is considered bad practice in C. Having the cast when using C is not a guaranteed problem, but can be for the reasons cited in the link.

There are other problems with this code as well, including the function addTransaction. If you get stuck with those, post another question with a mcve.

ryyker
  • 22,849
  • 3
  • 43
  • 87
  • I did the changes but still get segmenation fault when i start it. Even do i put a printf in the start of the code exit with segmentation fault and doesn't print anything – Matteo Pagliarello Jul 21 '22 at 20:22
  • @MatteoPagliarello - Have you run your program in debug, with break points in the spots where you suspect the problem occurs? Stepping through the code one line at a time will likely show you where exactly in your code the problem occurs, and from there the reason for the problem can likely be determined. (for example [debugging in gcc](https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html)). – ryyker Jul 21 '22 at 20:36
  • @MatteoPagliarello - I would suggest temporarily removing user input and hard code the value at top of main function. ( i.e. `id = 10;` ) Then also temporarily remove `shm...()` functions. If the seg-fault goes away, [then they are the culprit](https://stackoverflow.com/a/46505572/645128). What are your permissions? – ryyker Jul 21 '22 at 20:42
  • I tried to run debug but it says that failed at start and exit with value -1 – Matteo Pagliarello Jul 21 '22 at 20:55
  • Oh yes maybe the atoi could be a problem – Matteo Pagliarello Jul 21 '22 at 20:56
  • Maybe was atoi, cause argv[1] is filled by a process father. But when i launch only the child to test obv it gave me seg. fault. – Matteo Pagliarello Jul 21 '22 at 21:00
  • But now give me back floating point exeception :( – Matteo Pagliarello Jul 21 '22 at 21:01
  • @MatteoPagliarello - You've got some weird stuff going on. Get rid of `argv[1]` and hard code the value, as I suggested before, and the rest too. If I was on Linux I might be able to help further. But I am not. Good luck, sorry I could not help further. Have you considered `shmget()` may have a bad argument, and it is the cause. Or that your permissions are not high enough to call? (See my earlier link _then they are the culprit_.) – ryyker Jul 21 '22 at 21:16