1
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
//#include<mathscall.h>
#include<time.h>
#include"plot.h"

int main()
{
    int no_packets = 10000;
    //float lamda = 0.1;
    double lamda = 0.1,*lamdas;
    int i,j,cumulative_X,count = 0;
    int trans_time = 1;
    double temp,*throughput;
    int iterations = 1/0.1;
    printf("Iterations: %d\n",iterations);
    throughput = (float *)malloc(iterations*sizeof(float));
    lamdas = (float *)malloc(iterations*sizeof(float));
        int *pkt_collision;
    double *pkt_holder;
    int k=0;
    float p;
    for(p=0.1;p<1.1;p=p+0.1)
     {
        lamdas[k]=p;
         printf("lamdas: %f\n",lamdas[k]);
         k++;
        //printf("k: %d\n",k);
     }
    int l=0;

    while(lamda<1.1)
    {
         count = 0;
         temp = lamdas[l] * no_packets;
         int avg_packets = (int)temp;
         //printf("In here\n");
         pkt_holder = (double *)malloc(avg_packets*sizeof(double));
         pkt_collision = (int *)malloc(avg_packets*sizeof(int));
         //temp = lamda * no_packets;
         //printf("In here\n");
         srand(0);

         for(i=0;i<avg_packets;i++)
         {
            pkt_holder[i] = 0.0;
            pkt_collision[i] = 0;
         }

        for(i=1;i<avg_packets;i++)
        {

              double X;
              do
              {
                X= (rand() % 10000) / 10000.0;

              }while(X == 0);

                  double time_temp = -(double)log(X)/lamda;
             //printf("i: %d\t time_temp: %f\n ",i,time_temp);
              pkt_holder[i]=pkt_holder[i-1] + time_temp;

}



for(i=1;i<avg_packets;i++)
{
             for(j=i;j<avg_packets;j++)
             {
                if((pkt_holder[j]-pkt_holder[i-1])<=5 &&pkt_collision[j]==1)
                {

                     pkt_collision[j] = 1;
                     pkt_collision[i-1] = 1;
                 }
                 else
                    break;
            }
        }

for(i=0;i<avg_packets;i++)
{
             if(pkt_collision[i] == 0)

             {

                count++;
             }
 }
        throughput[l] = (float) count/no_packets;

        lamda+=0.1;
    free(pkt_holder);
        free(pkt_collision);// glibc error occuring after execution of this //statement
        l++;
 }


 printf("Sucess: %d\n",count);
 return 0;
}

In this program I am trying to simulate throughput of pure aloha.

Beginning from lamda 0.1 to lamda = 1, I am trying to find the throughput corresponding to these values.

In while loop I am trying to reallocate the size of both pkt_holder and pkt_collision in each iteration by freeing their memory at the ending of each iteration of loop.

When I tried to debug in eclipse it is showing glibc error when free(pkt_collision) is executed.

Any help or advice would be greatly appreciated.

Thank you

Floris
  • 45,857
  • 6
  • 70
  • 122
shreyas
  • 115
  • 1
  • 8

2 Answers2

4

This is why you should never do:

double *lamdas;
lamdas = (float *)malloc(iterations*sizeof(float));

This mis-matches and allocated half the expected space. It should be:

lambdas = malloc(iterations * sizeof *lambdas);

Don't manually repeat the type, it's risky and verbose. "Lock" it to the destination pointer and use sizeof.

Also, don't cast the return value of malloc() in C.

Community
  • 1
  • 1
unwind
  • 391,730
  • 64
  • 469
  • 606
  • Good catch on the type mismatch. I think that using a floating point loop counter may also be a source of problems. – Floris Jan 31 '14 at 14:28
  • 1
    Just a small correction: use `sizeof(*lambdas)` instead of `sizeof *lambdas`. – barak manos Jan 31 '14 at 16:00
  • Note the same issue arises with `throughput` but the error is most likely caused by this one. Ironic since the array is allocated and filled but never used. – Floris Jan 31 '14 at 16:43
3

I suspect that you are overwriting something in the following sequence:

lamdas = (float *)malloc(iterations*sizeof(float));
    int *pkt_collision;
double *pkt_holder;
int k=0;
float p;
for(p=0.1;p<1.1;p=p+0.1)
 {
    lamdas[k]=p;
     printf("lamdas: %f\n",lamdas[k]);
     k++;
    //printf("k: %d\n",k);
 }

You allocate iterations slots for lamdas, but when you iterate, you don't iterate with an integer index, but with a floating point index. Thus you might get one more iteration than you think (this has to do with inability to represent 0.1 exactly in floating point).

The solution is to write

for(int k = 0; k < iterations; k++) {
  lamdas[k] = 0.1 * (k+1);
  // etc
}

Since the pointer *pkt_collision is stored right after lamdas, and since most compilers store some information required for free right before the pointer (this is not by standard, but this is my experience), writing past the end of the allocated space for lamdas does, in fact, write exactly into the space that is used by free.

I think this will solve it.

EDIT just noticed that you are declaring lamdas as double*, but casting the pointer to it as a float*. Didn't you see the compiler warning?

ALWAYS ENABLE COMPILER WARNINGS, AND HEED THEM

So you have two problems. You need to allocate enough memory:

lamdas = malloc(iterations * sizeof(double));

and use an integer as your loop variable.

As an aside, you can prevent this problem in future by writing

lamdas = malloc(iterations * sizeof(*lamdas));

This way you don't have to remember what type it was - the compiler will know, and get it right.

UPDATE Compiling your code with gcc -Wall gives:

temp.c:16:16: warning: incompatible pointer types assigning to 'double *' from
      'float *' [-Wincompatible-pointer-types]
    throughput = (float *)malloc(iterations*sizeof(float));
               ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
temp.c:17:12: warning: incompatible pointer types assigning to 'double *' from
      'float *' [-Wincompatible-pointer-types]
    lamdas = (float *)malloc(iterations*sizeof(float));
           ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
temp.c:12:9: warning: unused variable 'trans_time' [-Wunused-variable]
    int trans_time = 1;
        ^
temp.c:11:13: warning: unused variable 'cumulative_X' [-Wunused-variable]
    int i,j,cumulative_X,count = 0;

The answer is right there in front of you. It is a REALLY good idea to compile with all warnings enabled, and improve your code until all warnings are gone. This is just one more example of why that is true.

FINAL(?) edit

I found a few more inconsistencies in your code. Here is the complete, working version.

A few things to note:

  • to get a random number between 0 and 1 (not including 0) probably the best thing to do is:

(rand()+1.0)/RAND_MAX

Using the % operator will give you a non-uniform distribution (greater chance of smaller numbers - try it and you will see).

  • you test for a collision flag being set when you look for collisions - this means no collisions will be found / counted (you only allow collisions with packets that have had collisions...)
  • I made some changes in the code according to the things I mentioned above
  • I added some printf statements
  • I fixed some formatting / indentation

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>

int main()
{
  int no_packets = 10000;
  double lamda = 0.1,*lamdas;
  int i,j,cumulative_X,count = 0;
  int trans_time = 1;
  double temp,*throughput;
  int iterations = 1/0.1;
  printf("Iterations: %d\n",iterations);
  throughput = malloc(iterations*sizeof(*throughput));
  lamdas = malloc(iterations*sizeof(*lamdas));
  int *pkt_collision;
  double *pkt_holder;
  int k=0;
  float p;
  for(k=0; k<iterations;k++)
  {
    lamdas[k]=0.1*(k+1);
    printf("lamdas: %f\n",lamdas[k]);
  }

  int l=0;

  while(lamda<1.05) // to avoid rounding errors
  {
    count = 0;
    temp = lamdas[l] * no_packets;
    int avg_packets = (int)temp;
    pkt_holder = (double *)malloc(avg_packets*sizeof(double));
    pkt_collision = (int *)malloc(avg_packets*sizeof(int));
    srand(0);

    for(i=0;i<avg_packets;i++)
    {
      pkt_holder[i] = 0.0;
      pkt_collision[i] = 0;
    }

    printf("lamda = %.1f; avg_packets = %d\n", lamda, avg_packets);
    int totalTried = 0;
    for(i=1;i<avg_packets;i++)
    {
      double X;
      do
      {
        //X = (rand() % 10000) / 10000.0;
        X = rand() / (double)RAND_MAX;
      } while(X == 0);

      double time_temp = -(double)log(X)/lamda;
      pkt_holder[i]=pkt_holder[i-1] + time_temp;
    }

    for(i=1;i<avg_packets;i++)
    {
      for(j=i;j<avg_packets;j++)
      {
        if((pkt_holder[j]-pkt_holder[i-1])<=5) // &&pkt_collision[j]==1)
        {
          pkt_collision[j] = 1;
          pkt_collision[i-1] = 1;
        }
        else
          break;
      }
    }

    for(i=0;i<avg_packets;i++)
    {
      if(pkt_collision[i] == 0)
      {
        count++;
      }
    }
    throughput[l] = (float) count/no_packets;
    printf("count = %d; throughput[%d] = %f\n", count, l, throughput[l]);
    printf("freeing now...\n");
    free(pkt_holder);
    free(pkt_collision);
    lamda+=0.1;
    l++;
  }

  printf("Sucess: %d\n",count);
  return 0;
}
Floris
  • 45,857
  • 6
  • 70
  • 122