检测到glibc错误,不知道出了什么问题

时间:2014-01-31 14:15:28

标签: c

#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;
}

在这个程序中,我试图模拟纯粹的aloha的吞吐量。

lamda 0.1开始到lamda = 1,我试图找到与这些值对应的吞吐量。

在while循环中,我试图通过在循环的每次迭代结束时释放它们的内存来重新分配每次迭代中pkt_holder和pkt_collision的大小。

当我尝试在eclipse中调试时,执行free(pkt_collision)时显示glibc错误。

非常感谢任何帮助或建议。

谢谢

2 个答案:

答案 0 :(得分:4)

这就是你永远不应该这样做的原因:

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

这种错误匹配并分配了预期空间的一半。它应该是:

lambdas = malloc(iterations * sizeof *lambdas);

不要手动重复这种类型,它有风险和冗长。将其“锁定”到目标指针并使用sizeof

另外,don't cast the return value of malloc() in C

答案 1 :(得分:3)

我怀疑你是按照以下顺序覆盖的东西:

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);
 }

您为iterations分配lamdas个插槽,但是在迭代时,不会使用整数索引进行迭代,而是使用浮点索引进行迭代。因此,您可能会得到比您想象的更多的迭代(这与无法在浮点中完全表示0.1)。

解决方案是写

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

由于指针*pkt_collision存储在lamdas之后,并且由于大多数编译器在指针之前存储free所需的一些信息(这不是标准的,但这是我的经验),写出lamdas分配的空间的末尾确实写入了free所使用的空间。

我认为这会解决它。

编辑刚刚注意到您将lamdas声明为double*,但将指针指向float*。你没有看到编译器警告吗?

始终启用编译器警告,并将其解决

所以你有两个问题。你需要分配足够的内存:

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

并使用整数作为循环变量。

另外,您可以通过编写

来防止此问题
lamdas = malloc(iterations * sizeof(*lamdas));

这样你就不必记住它是什么类型 - 编译器会知道,并且正确。

<强>更新 使用gcc -Wall编译代码会产生:

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;

答案就在你面前。在启用所有警告的情况下进行编译是一个非常好的主意,并且在所有警告消失之前改进代码。这只是为什么这是真实的另一个例子。

最终(?)修改

我发现代码中存在一些不一致之处。这是完整的工作版本。

有几点需要注意:

  • 得到0到1之间的随机数(不包括0)可能最好的办法是:

(rand()+1.0)/RAND_MAX

使用%运算符会给你一个非均匀分布(更小数字的可能性更小 - 尝试一下,你会看到)。

  • 您在查找碰撞时测试是否设置了collision标志 - 这意味着不会发现/计算任何碰撞(您只允许与发生碰撞的数据包发生碰撞......)
  • 我根据上面提到的内容对代码进行了一些更改
  • 我添加了一些printf语句
  • 我修复了一些格式/缩进

#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;
}