总线错误 - 不确定原因 [英] Bus error--not sure why

查看:89
本文介绍了总线错误 - 不确定原因的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码用gcc编译,但是当我运行可执行文件时,会返回一个总线错误。任何想法?


#include< stdio.h>

#include< string.h>

#include< ; stdlib.h>

/ *生成序列号列表* /

int main(无效){


char appname [ ] =MYAPP; //新应用

char myserial [100]; //序列号的指针变量

int count = 20000; //序列号的数量

int i; //索引号;

char * serials [count + 1]; //完整的序列号列表

int seriallength; //序列号长度

char * serialblock; //序列号的内存块


//修剪应用程序名称

char * shortname =(char *)malloc(2);

strncpy(短名称,appname,2);

免费(短名称);


//构建序列号数组

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

int five = i * 5; //序列数组的第一个数字

int eleven = i / 11; //第二个数字

int one =(i-1); //第三个数字

sprintf(myserial,"%s-%i-%i-%i-%s",appname,five,11,one,

shortname); //将组件值分配给序列号字符串

seriallength = strlen(myserial); //序列号的长度

serialblock =(char *)malloc(seriallength + 1); //分配内存

for serial

if(serialblock == NULL){

返回0; //检查空内存

}


strcpy(serialblock,myserial); //将数据复制到序列号的地址

来自序列号的块

serials [i] = serialblock; //将串行块地址的数据分配给

连续数组的下一个版本


free(serialblock); //免费记忆

}


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

printf ("%s \ n",i,serials [i]);

}


返回0;


}


-

Kevin Walzer

凯文代码
http://www.codebykevin.com

解决方案

Kevin Walzer< kw@codebykevin.comwrote:


以下代码用gcc编译,但在运行时返回总线错误

可执行文件。有任何想法吗?


#include< stdio.h>

#include< string.h>

#include< stdlib.h>


/ *生成序列号列表* /

int main(void){


char appname [] =" MYAPP" ;; //新应用

char myserial [100]; //序列号的指针变量

int count = 20000; //序列号的数量

int i; //索引号;

char * serials [count + 1]; //完整的序列号列表



当你的lop只从1运行到'count'1'时,为什么''count + 1''?


int seriallength; //序列号长度

char * serialblock; //序列号
的内存块


//修剪应用程序名称

char * shortname =(char *)malloc (2);

strncpy(短名,appname,2);

free(短名);



最后三行是NOP。你分配内存,复制

的东西并解除分配(并且转换返回

值的malloc()没有多大意义)。


//构建序列号数组

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

int five = i * 5; //序列数组的第一个数字

int eleven = i / 11; //第二个数字

int one =(i-1); //第三个数字

sprintf(myserial,"%s-%i-%i-%i-%s",appname,five,11,one,

shortname); //将组件值分配给序列号字符串



你不能再使用''短名'了,你已经解除了什么

它指向。即使你没有它也不会是一个

字符串,因为没有尾随的''\ 0''字符(请阅读

strncpy的描述()再次仔细注意如果源字符串比你允许的更长的时间内是什么,那么
笔是复制的。所以,即使这样使用%s也是如此。不是一个选择,因为它重新/

需要一个字符串。如果你没有取消分配内存

,你可以使用%。2s打印出来。 (保持

printf()使用超过前两个字符)。但是,然后

你可以通过使用%。2s来获得相同的效果。使用''appname'',

所以''短名''的使用似乎相当无用。


seriallength = strlen (myserial); //序列号的长度

serialblock =(char *)malloc(seriallength + 1); //分配内存

for serial

if(serialblock == NULL){

返回0; //检查空内存

}


strcpy(serialblock,myserial); //将数据复制到序列号的地址

来自序列号的块

serials [i] = serialblock; //将串行块地址的数据分配给

下一个连续数组的数字


free(serialblock); //免费记忆



现在''连续剧[i]''指向免费记忆你不被允许

用于任何事物。你好像假设只持有

一个指向某个东西的指针会保留它所指向的东西,

但事实并非如此。 (也许你太习惯用GC了?)一种方法是不要解除分配

''serialblock''但是只需将指针存放在''连续符号''

数组中,只有在你不需要时才释放内存

了(例如在printf()之后稍后)。


}


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

printf("%s \ n",i,serials [i]);



这里你使用已经解除分配的内存指针

一次又一次。


}


返回0;



你确定你得到一个总线错误(我猜这意味着一个SIGBUS)

而不是分段错误(SIGSEGV )?


问候,Jens

-

\ Jens Thoms Toerring ___ jt@toerring.de

\ __________________________ http ://toerring.de


2008年7月24日星期四20:35:41 -0400,Kevin Walzer< kw@codebykevin.com>

写道:


>以下代码使用gcc编译,但在运行可执行文件时返回总线错误。任何想法?

#include< stdio.h>
#include< string.h>
#include< stdlib.h>

/ *生成序列号列表* /
int main(无效){


char appname [] =" MYAPP" ;; //新应用

char myserial [100]; //序列号的指针变量

int count = 20000; //序列号的数量

int i; //索引号;

char * serials [count + 1]; //完整的序列号列表

int seriallength; //序列号长度

char * serialblock; //序列号的内存块


//修剪应用程序名称

char * shortname =(char *)malloc(2);



不要从malloc投出回报。它没有任何帮助,可以

压制你真正想要看到的诊断信息。


strncpy(shortname,appname, 2);



这会通过写你已经分配的

内存来调用未定义的行为。 appname包含6个字符。你为2分配了空间。

格言在5磅重的袋子里大约10磅。


free(shortname);



在许多安装中,写入超出分配的内存会搞砸

内部分配控制表和免费变得非常混乱。


这三个陈述的重点是什么?你分配内存,

复制到它,然后释放它而不完成任何事情。


>

//构建序列号数组

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

int five = i * 5; //序列数组的第一个数字

int eleven = i / 11; //第二个数字

int one =(i-1); //第三个数字

sprintf(myserial,"%s-%i-%i-%i-%s",appname,five,11,one,
短名称); / /将组件值分配给序列号字符串



更多未定义的行为。你释放了短名。您不能尝试访问
来访问它曾经指向的内存。事实上,你不能为任何目的评估它包含的值。


seriallength = strlen(myserial); //序列号的长度

serialblock =(char *)malloc(seriallength + 1); //为串口分配内存

if(serialblock == NULL){

返回0; //检查空内存



当程序失败时返回成功有点奇怪。


}


strcpy(serialblock,myserial); //将数据复制到序列号的地址
块来自串口



这就是为什么你不应该在usenet帖子中使用//注释。


serials [i] = serialblock; //将串行块地址的数据分配给
下一个连续数组的数据


free(serialblock); //可用内存



这会释放serial [i]指向的内存。


}

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

printf("%s\ n,i,serials [i]);



这会调用未定义的行为,因为你不再拥有用于指向的

内存序列[i]。
< blockquote class =post_quotes>
> }


返回0;

}



删除电子邮件的del


Barry Schwarz写道:


On Thu,2008年7月24日20:35:41 -0400,Kevin Walzer< kw @ codebykevin.com>

写道:


>以下代码用gcc编译,但在运行时返回总线错误
可执行文件。任何想法?

#include< stdio.h>
#include< string.h>
#include< stdlib.h>

/ *生成序列号列表* /
int main(无效){

char appname [] =" MYAPP" ;; //新应用
char myserial [100]; //序列号的指针变量
int count = 20000; //序列号的数量
int i; //索引号;
char * serials [count + 1]; //完整的序列号列表
int seriallength; //序列号长度
char * serialblock; //序列号的内存块
//修剪应用程序名称
char * shortname =(char *)malloc(2);



不要从malloc投出回报。它没有任何帮助,可以

抑制你真正想要看到的诊断信息。


> strncpy(shortname,appname,2);



这会通过写你已经分配的

内存来调用未定义的行为。 appname包含6个字符。你为2分配了空间。

格言适用于5磅重的10磅左右。



...但是放入不超过两个char的6个字符串
字符串就可以了(除非malloc()返回NULL) 。注意

使用strncpy()而不是strcpy() - 当然,两个

字符{''M'',''Y''}做不构成''\0'' - 终止

字符串,但这在这里几乎不重要,因为这个无意义的代码所做的下一个

的事情是


>自由(短名称);



[有用分析的剩余部分剪断]



-

Eric索斯曼
es*****@ieee-dot-org.inva lid


The following code compiles with gcc but returns a bus error when I run
the executable. Any ideas?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* generate serial number list*/
int main (void) {

char appname[] = "MYAPP"; //new app
char myserial[100]; //pointer variable for serial numbers
int count = 20000; //number of serial numbers
int i; //index number;
char *serials[count+1]; //full list of serial numbers
int seriallength; //length of serial number
char *serialblock; //block of memory for serial number

//trim application name
char *shortname = (char *) malloc(2);
strncpy(shortname, appname, 2);
free(shortname);

//build the serial number array
for (i = 1; i < count; ++i) {
int five = i*5; //first number of the serial array
int eleven = i/11; //second number
int one = (i-1); //third number
sprintf(myserial, "%s-%i-%i-%i-%s", appname, five, eleven, one,
shortname);//assign component values to serial number string
seriallength=strlen(myserial); //length of serial number
serialblock = (char *) malloc(seriallength + 1); //allocate memory
for serial
if (serialblock == NULL) {
return 0; //check for null memory
}

strcpy(serialblock, myserial); //copy data to address of serial
block from serial
serials[i]=serialblock; //assign data at serial block address to
next indeas of serials array

free(serialblock); //free memory
}

for (i = 1; i < count; ++i) {
printf(" %s\n", i, serials[i]);
}

return 0;

}

--
Kevin Walzer
Code by Kevin
http://www.codebykevin.com

解决方案

Kevin Walzer <kw@codebykevin.comwrote:

The following code compiles with gcc but returns a bus error when I run
the executable. Any ideas?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/* generate serial number list*/
int main (void) {

char appname[] = "MYAPP"; //new app
char myserial[100]; //pointer variable for serial numbers
int count = 20000; //number of serial numbers
int i; //index number;
char *serials[count+1]; //full list of serial numbers

Why ''count+1'' when your lop only runs from 1 to ''count-1''?

int seriallength; //length of serial number
char *serialblock; //block of memory for serial number

//trim application name
char *shortname = (char *) malloc(2);
strncpy(shortname, appname, 2);
free(shortname);

The last three lines are a NOP. You allocate memory, copy
something to it and deallocate it (and casting the return
value of malloc() doesn''t make much sense).

//build the serial number array
for (i = 1; i < count; ++i) {
int five = i*5; //first number of the serial array
int eleven = i/11; //second number
int one = (i-1); //third number
sprintf(myserial, "%s-%i-%i-%i-%s", appname, five, eleven, one,
shortname);//assign component values to serial number string

You can''t use ''shortname'' anymore, you already deallocated what
it was pointing to. And even if you hadn''t it would not be a
string since there is no trailing ''\0'' character (please read
the description of strncpy() again and carefully note what hap-
pens if the source string is longer than what you allow to be
copied). So even then using "%s" isn''t an option since it re-
quires a string. If you wouldn''t have deallocated the memory
you would have been able to print it out using "%.2s" (to keep
printf() from using more than the first two chars). But then
you could get the same effect by using "%.2s" with ''appname'',
so the whole use of ''shortname'' seems to be rather useless.

seriallength=strlen(myserial); //length of serial number
serialblock = (char *) malloc(seriallength + 1); //allocate memory
for serial
if (serialblock == NULL) {
return 0; //check for null memory
}

strcpy(serialblock, myserial); //copy data to address of serial
block from serial
serials[i]=serialblock; //assign data at serial block address to
next indeas of serials array

free(serialblock); //free memory

And now ''serials[i]'' points to free-ed memory you aren''t allowed
to use for anything at all. You seem to assume that just holding
a pointer to something would keep what it points to in existence,
but that''s not the case. (Perhaps you''re too much used to a lan-
guage with a GC?) One way to go would be to not deallocate
''serialblock'' but just keep the pointer stored in the ''serials''
array and deallocate the memory only when you don''t need it
anymore (e.g. after the printf() later on).

}

for (i = 1; i < count; ++i) {
printf(" %s\n", i, serials[i]);

And here you use pointers to memory that already has been deallocated
again and again.

}

return 0;

Are you sure you''re getting a bus error (I guess that means a SIGBUS)
instead of a segmentation fault (SIGSEGV)?

Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de


On Thu, 24 Jul 2008 20:35:41 -0400, Kevin Walzer <kw@codebykevin.com>
wrote:

>The following code compiles with gcc but returns a bus error when I run
the executable. Any ideas?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* generate serial number list*/
int main (void) {

char appname[] = "MYAPP"; //new app
char myserial[100]; //pointer variable for serial numbers
int count = 20000; //number of serial numbers
int i; //index number;
char *serials[count+1]; //full list of serial numbers
int seriallength; //length of serial number
char *serialblock; //block of memory for serial number

//trim application name
char *shortname = (char *) malloc(2);

Don''t cast the return from malloc. It doesn''t help anything and can
suppress a diagnostic message you would really want to see.

strncpy(shortname, appname, 2);

This invokes undefined behavior by writing beyond you allocated
memory. appname contains 6 char. You allocated space for 2. The
adage about 10 pounds in a 5 pound bag applies.

free(shortname);

On many installations, writing beyond allocated memory messes up
internal allocation control tables and free gets very confused.

What is the point of these three statements? You allocate memory,
copy into it, and then free it without accomplishing anything.

>
//build the serial number array
for (i = 1; i < count; ++i) {
int five = i*5; //first number of the serial array
int eleven = i/11; //second number
int one = (i-1); //third number
sprintf(myserial, "%s-%i-%i-%i-%s", appname, five, eleven, one,
shortname);//assign component values to serial number string

More undefined behavior. You freed shortname. You cannot attempt to
access the memory it used to point to. In fact, you cannot evaluate
the value it contains for any purpose.

seriallength=strlen(myserial); //length of serial number
serialblock = (char *) malloc(seriallength + 1); //allocate memory
for serial
if (serialblock == NULL) {
return 0; //check for null memory

It is a little strange to return success when your program failed.

}

strcpy(serialblock, myserial); //copy data to address of serial
block from serial

This is why you should not use // comments in a usenet post.

serials[i]=serialblock; //assign data at serial block address to
next indeas of serials array

free(serialblock); //free memory

This releases the memory that serial[i] points to.

}

for (i = 1; i < count; ++i) {
printf(" %s\n", i, serials[i]);

And this invokes undefined behavior because you no longer own the
memory serial[i] used to point to.

> }

return 0;

}


Remove del for email


Barry Schwarz wrote:

On Thu, 24 Jul 2008 20:35:41 -0400, Kevin Walzer <kw@codebykevin.com>
wrote:

>The following code compiles with gcc but returns a bus error when I run
the executable. Any ideas?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* generate serial number list*/
int main (void) {

char appname[] = "MYAPP"; //new app
char myserial[100]; //pointer variable for serial numbers
int count = 20000; //number of serial numbers
int i; //index number;
char *serials[count+1]; //full list of serial numbers
int seriallength; //length of serial number
char *serialblock; //block of memory for serial number

//trim application name
char *shortname = (char *) malloc(2);


Don''t cast the return from malloc. It doesn''t help anything and can
suppress a diagnostic message you would really want to see.

> strncpy(shortname, appname, 2);


This invokes undefined behavior by writing beyond you allocated
memory. appname contains 6 char. You allocated space for 2. The
adage about 10 pounds in a 5 pound bag applies.

... but putting not more than two char of a six-char
string is fine (unless malloc() returned NULL). Note the
use of strncpy() instead of strcpy() -- of course, the two
characters { ''M'', ''Y'' } do not constitute a ''\0''-terminated
string, but that scarcely matters here because the next
thing this pointless piece of code does is

> free(shortname);

[remainder of helpful analysis snipped]

--
Eric Sosman
es*****@ieee-dot-org.invalid


这篇关于总线错误 - 不确定原因的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆