随机双自由或损坏(输出)C
我正面临一个让我发疯的问题 我有一个函数,这个函数:随机双自由或损坏(输出)C,c,C,我正面临一个让我发疯的问题 我有一个函数,这个函数: void load_weapons3(t_env *e, char *name, int x, t_weapon *w) { char *tmp; char *fname; t_image i; fname = NULL; tmp = NULL; tmp = ft_get_name_without_extention(name); if (!tmp)
void load_weapons3(t_env *e, char *name, int x, t_weapon *w)
{
char *tmp;
char *fname;
t_image i;
fname = NULL;
tmp = NULL;
tmp = ft_get_name_without_extention(name);
if (!tmp)
return ;
fname = ft_strcat(tmp, "_fire.xpm");
free(tmp);
if (!fname)
return ;
i.image = mlx_xpm_file_to_image(e->mlx_ptr, fname, &(i.x), &(i.y));
if (!i.image)
{
(*w).fire = NULL;
return ;
}
else
(*w).fire = malloc(sizeof(t_weaponfire) * QTY_OF_FIRE);
i.image_data = mlx_get_data_addr(i.image,
&(i.bpp),
&(i.size_line),
&(i.endian));
i.image_tab = get_image_tab(i);
load_weapon_fire(e, x, i);
printf("%s\n", fname);
free(fname);
}
可能相关的代码的其他部分:
int ft_strlen(char *str)
{
int i;
i = 0;
while (str[i])
i++;
return (i);
}
char *ft_strcpy(char *str)
{
int i;
int j;
char *cpystr;
j = 0;
i = ft_strlen(str);
cpystr = malloc(sizeof(char) * (i + 1));
while (j < i)
{
cpystr[j] = str[j];
j++;
}
cpystr[j] = '\0';
return (cpystr);
}
char *ft_get_name_without_extention(char *fullpath)
{
char *str;
int i;
i = ft_strlen(fullpath);
str = ft_strcpy(fullpath);
while (i)
{
if (str[i] == '.')
{
str[i] = '\0';
return (str);
}
i--;
}
free(str);
return (NULL);
}
char *ft_strcat(char *str1, char *str2)
{
int i;
int len1;
int len2;
char *str;
i = 0;
str = NULL;
if (!str1 || !str2)
return (NULL);
len1 = ft_strlen(str1);
len2 = ft_strlen(str2);
str = malloc(sizeof(char) * (len1 + len2 + 1));
if (!str)
return (NULL);
while (i < len1)
str[i] = str1[i++];
len1 = 0;
while (len1 < len2)
str[i + len1] = str2[len1++];
str[i + len1] = '\0';
return (str);
}
void load_weapons(t_env *e)
{
int xpm_q;
DIR *d;
struct dirent *dir;
xpm_q = ft_get_xpm_quantity("img/weapons");
printf("Xpm_q is : %d\n", xpm_q);
if (xpm_q > 0)
{
e->weapons.weapons_count = xpm_q;
e->weapons.weapons = malloc(sizeof(t_image) * (xpm_q + 1));
xpm_q--;
d = opendir("img/weapons");
if (d)
{
while ((dir = readdir(d)) != NULL)
{
load_weapons2(&xpm_q, &(e->weapons.weapons[xpm_q]), e, dir->d_name);
}
closedir(d);
}
}
e->weapons.selected_weapon = 0;
}
void load_weapons2(int *xpm_quantity, t_weapon *w, t_env *e, char *n)
{
char *fname;
t_image *i;
if (!ft_have_extension(".xpm\0", n) || ft_have_extension("_fire.xpm\0", n))
return ;
i = &(w->image);
fname = ft_strcat("img/weapons/", n);
i->name = ft_strcpy(n);
i->image = mlx_xpm_file_to_image(e->mlx_ptr, fname, &(i->x), &(i->y));
i->image_data = mlx_get_data_addr(i->image,
&(i->bpp),
&(i->size_line),
&(i->endian));
i->image_tab = get_image_tab((*i));
load_weapons3(e, fname, *xpm_quantity, w);
free(fname);
(*xpm_quantity)--;
}
int ft\u strlen(char*str)
{
int i;
i=0;
while(str[i])
i++;
回报(i);
}
char*ft\u strcpy(char*str)
{
int i;
int j;
char*cpystr;
j=0;
i=ft_strlen(str);
cpystr=malloc(sizeof(char)*(i+1));
而(j0)
{
e->wearms.wearms\u count=xpm\u q;
e->wearms.wearms=malloc(sizeof(t_图像)*(xpm_q+1));
xpm_q--;
d=opendir(“img/武器”);
如果(d)
{
而((dir=readdir(d))!=NULL)
{
加载武器2(&xpm_q,&(e->wearms.wearms[xpm_q]),e,dir->d_name);
}
closedir(d);
}
}
e->wearms.selected_-wearm=0;
}
空装武器2(整数*xpm\u数量,t\u武器*w,t\u环境*e,字符*n)
{
char*fname;
t_图像*i;
如果(!ft_有扩展名(“.xpm\0”,n)| ft_有扩展名(“_fire.xpm\0,n))
返回;
i=&(w->image);
fname=ft_strcat(“img/武器/”,n);
i->name=ft\u strcpy(n);
i->image=mlx\u xpm\u文件到图像(e->mlx\u ptr,fname,&(i->x),&(i->y));
i->image\u data=mlx\u get\u data\u addr(i->image,
&(i->bpp),
&(i->尺寸线),
&(i->endian));
i->image_tab=get_image_tab((*i));
装载武器3(e,fname,*xpm\u数量,w);
免费(fname);
(*xpm_数量)--;
}
有时(实际上是随机的)我会得到一个“双重自由或腐败(out)”,这似乎是在我释放fname指针时发生的。事实上,我没有双重释放它,printf打印它没有任何问题
如果有人有线索
我正在使用gcc(ubuntu4.8.4-2ubuntu1~14.04)4.8.4,在VirtualBox中运行
谢谢你的阅读 您的代码很糟糕,您仍然没有发布您的
typedef
s和struct
-定义,这些定义将在以下内容中变得相关:
因此,在load\u wearms()
中,您malloc()
一个数组
e->weapons.weapons = malloc(sizeof(t_image) * (xpm_q + 1));
其内容可能是t\u image
类型。然后将指向数组中倒数第二个有效对象的指针传递到load\u weapons2()
(很好的描述性名称)
但是等等!再次装载武器2()的原型是什么
void load_weapons2(int *, t_weapon *, t_env *, char *)
那不是t\u图像*
,那是t\u武器*
!震惊和敬畏,然后你不知何故从一个t\u武器*
中提取出一个t\u图像*
,这实际上是一个t\u图像*
t_image *i;
i = &(w->image);
最后一行有意义的唯一方法是,如果t\u武器
有一个成员t\u图像
,这显然需要sizeof(t\u武器)>=sizeof(t\u图像)
。因此,除非t_image
是t_武器
的唯一成员,否则您分配的空间不足
现在我们来听听一些完全不请自来的建议:完全重写您应该发布所有相关代码。例如,
ft\u是否在没有扩展()的情况下获取\u name\u
分配一个足够大的缓冲区来连接“\u fire.xpm”
,而不会溢出?不确定您想做什么,但尝试删除if(fname)free(fname)代码>因为fname
不是由malloc
或family分配的。您在哪里将内存分配给fname
?这里非常推荐使用valgrind
。使用--leak check=yes
有关详细信息,请参阅《快速入门指南》。@GlobCoder:不,一切都不是很好,只是因为删除该代码后不会立即崩溃。它与代码一起崩溃的事实强烈地表明,代码就像它看起来一样糟糕。此外,它还缺少代码。重写肯定会带来好处。正如您所指出的,我将重点关注描述性名称,加上有意义的注释,以及一些基本内容,如整洁的格式,以帮助可读性。学习更好的代码通常是从一些相当粗糙的工作开始的,我知道我已经写了我的分享。不过我明白了。你们完全正确,问题来自e->wearms.wearms的分配,这是一个t_武器,显然不是t_图像。我知道我的代码很糟糕,这是一项课业,我们必须遵守规范,将一个函数的行数限制为25行,每个文件的函数数不超过5行。因此,试图缩短它有时会使事情变得有点复杂,即使代码可以工作,从外部查看也会非常困难。。。尽管如此,我还是非常感谢您阅读并准确理解我的代码。我将为另一个2D libra重写所有内容
t_image *i;
i = &(w->image);