2011-09-16 89 views
2

我写以下代码:信号11(SIGSEGV)

FILE *book; 
wchar_t bufferln[FILE_READ_BUFFER]; 
wchar_t buffer[FILE_READ_BUFFER]; 
book = fopen(file, "r"); 
if(book == NULL){ 
    perror("Es ist ein Fehler beim lesen des Buches aufgetreten"); 
    return EXIT_FAILURE; 
} 
while(fgetws(buffer, FILE_READ_BUFFER, book) != NULL){ 
    if(wcscmp(buffer, L"\n") == 0){ 
     bufferln[0] = L'\0'; 
     continue; 
    } 
    buffer[wcsnlen(buffer, FILE_READ_BUFFER)-1] = L' '; 
    wcsncat(bufferln, buffer, FILE_READ_BUFFER); 
} 
return EXIT_SUCCESS; 

它崩溃与SIGSEGV。我跑Valgrind的,显示如下:

==11251== Conditional jump or move depends on uninitialised value(s) 
==11251== at 0x40BD5CF: wcsncat (wcsncat.c:36) 
==11251== by 0x804865D: read_book (book.c:18) 
==11251== by 0x804872B: main (main.c:19) 
==11251== Uninitialised value was created by a stack allocation 
==11251== at 0x80485B7: read_book (book.c:3) 
==11251== 
==11251== Invalid read of size 4 
==11251== at 0x40A58E2: fgetws (iofgetws.c:52) 
==11251== by 0x804867D: read_book (book.c:12) 
==11251== by 0x6D: ??? 
==11251== Address 0x65 is not stack'd, malloc'd or (recently) free'd 
==11251== 
==11251== 
==11251== Process terminating with default action of signal 11 (SIGSEGV) 
==11251== Access not within mapped region at address 0x65 
==11251== at 0x40A58E2: fgetws (iofgetws.c:52) 
==11251== by 0x804867D: read_book (book.c:12) 
==11251== by 0x6D: ??? 
==11251== If you believe this happened as a result of a stack 
==11251== overflow in your program's main thread (unlikely but 
==11251== possible), you can try to increase the size of the 
==11251== main thread stack using the --main-stacksize= flag. 
==11251== The main thread stack size used in this run was 8388608. 

我认为这个问题以某种方式与我wcsncat的使用(写入*本书内存也许?),但为什么呢? 我想逐段阅读文档(UTF-8),然后执行不在此代码中的内容。

回答

1

什么能发生的事情是,你的wcsncat(),它为每个文件的作用:

“ 描述 的wcsncat()函数将不超过字符串的第n个字符更多指向WS2到如果一个NULL字符出现在ws2前n个字符中,所有到NULL字符的字符都会附加到ws1中,ws2的第一个字符将覆盖ws1的终止NULL字符,NULL结尾字符是总是附加到的结果,以及如果用于复制重叠的对象,该行为是未定义。 “

因此,它通过覆盖第一次出现NULL字符开始继续追加到bufferln。因此,如果if(wcscmp(buffer,L“\ n”)== 0)返回FALSE,您将最终超出您分配的FILE_READ_BUFFER缓冲区并将文件泄漏到bufferln边界之外,最终可能会损坏堆栈。

在大多数情况下,栈向下增长,它必须达到实际上的错,因为访问的第一个2页的虚拟地址的页面是不允许在大多数系统上的一些地区。这是一个有争议的问题,为什么它在那里出错。但主要的原因是你必须在读取数据之后尝试写入数据,因为你的读写缓冲区长度相同。

HTH

+0

我希望wcsncat只能追加x个字符,直到w1达到n个字符。解决了,谢谢! –

0

如果该行是空的(\ n变由\ 0取代),字符串的长度为空,和strlen的(±)-1-缓冲以下点。

编辑: 我理解错了;你只是追加太多。增加缓冲区大小,读取较短的行,或两者。 并避免strcat();

+0

我用wcsncat至极需要缓冲区大小作为参数,进一步我只读FILE_READ_BUFFER迹象(相当于1000),并在每一个负责处理字符串函数中使用相同的常量。你的意思是什么? –

+0

对不起,我错了。 [我只是恨* str *猫()!只要继续计数...]。乔纳森可能是正确的:缓冲区只是未初始化。 – wildplasser

2

您不初始化bufferln,因此当您将新行连接到未初始化数据的末尾时(wcsncat()),您不知道代码要写入的位置。

您还在输入缓冲区buffer末尾的空终止符上写了一个(宽)空间,所以您不知道要将什么复制到随机位置;复制将在下一次遇到宽NUL时停止。

相关问题