Closed. This question is off-topic。它当前不接受答案。
想改善这个问题吗? Update the question,所以它是on-topic,用于堆栈溢出。
3年前关闭。
我正在尝试编写一个程序,该程序搜索文件中的模式并将其替换为一些子字符串。本质上,我将修改后的文本写入临时文件,删除原始文件,然后将临时文件重命名为原始文件名。我已经在单个文件上进行了逐一测试,这似乎工作正常。
下一步是递归执行操作,虽然它遍历了一些文件,并按应有的方式对其进行了修改,但到达某个点(在几次调用
所以我想检查一下gdb中的内容,而我很难理解:
我知道这与不良的内存分配或不释放某些指针有关?如果是这样,谁能指出我应该在哪里做?
还有可能我多次删除文件吗?这就是我从“双重自由腐败”的含义中得到的意思。
据我所知,我的递归遍历运行良好,因为它精确输出了我想要在
我决定包括整个代码,以防万一该错误与
想改善这个问题吗? Update the question,所以它是on-topic,用于堆栈溢出。
3年前关闭。
我正在尝试编写一个程序,该程序搜索文件中的模式并将其替换为一些子字符串。本质上,我将修改后的文本写入临时文件,删除原始文件,然后将临时文件重命名为原始文件名。我已经在单个文件上进行了逐一测试,这似乎工作正常。
下一步是递归执行操作,虽然它遍历了一些文件,并按应有的方式对其进行了修改,但到达某个点(在几次调用
replaceline()
之后),我得到了这个错误。*** Error in `/someplace/a.out': double free or corruption (top): 0x0000000000614090 ***
所以我想检查一下gdb中的内容,而我很难理解:
Program received signal SIGABRT, Aborted.
0x00007ffff7a4bcc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) backtrace
#0 0x00007ffff7a4bcc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1 0x00007ffff7a4f0d8 in __GI_abort () at abort.c:89
#2 0x00007ffff7a88394 in __libc_message (do_abort=do_abort@entry=1,
fmt=fmt@entry=0x7ffff7b96b28 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175
#3 0x00007ffff7a9466e in malloc_printerr (ptr=<optimized out>,
str=0x7ffff7b96c38 "double free or corruption (top)", action=1) at malloc.c:4996
#4 _int_free (av=<optimized out>, p=<optimized out>, have_lock=0) at malloc.c:3840
#5 0x00007ffff7a82ae5 in _IO_new_fclose (fp=0x614090) at iofclose.c:85
#6 0x0000000000400fa8 in replaceline (path=0x7fffffffdff0 "./toast/toast3/tt", patternoo=0x401357 "dime",
replacearoo=0x401352 "lime") at testrep7.c:91
#7 0x00000000004011c5 in recursiveWalk (pathName=0x7fffffffe440 "./toast/toast3", level=1) at testrep7.c:129
#8 0x000000000040118a in recursiveWalk (pathName=0x40135c "./toast", level=0) at testrep7.c:125
#9 0x000000000040122c in main (argc=2, argv=0x7fffffffe958) at testrep7.c:139
(gdb) frame 2
#2 0x00007ffff7a88394 in __libc_message (do_abort=do_abort@entry=1,
fmt=fmt@entry=0x7ffff7b96b28 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175
175 ../sysdeps/posix/libc_fatal.c: No such file or directory.
我知道这与不良的内存分配或不释放某些指针有关?如果是这样,谁能指出我应该在哪里做?
还有可能我多次删除文件吗?这就是我从“双重自由腐败”的含义中得到的意思。
据我所知,我的递归遍历运行良好,因为它精确输出了我想要在
replaceline()
中使用的路径。我决定包括整个代码,以防万一该错误与
replaceline()
以外的内容有关,尽管我确实认为这是出错的地方。很抱歉,如果代码太多,但是我不能完全确定我已设法将问题定位到某些功能。谢谢。#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <libgen.h>
int delete(char* file){
int status;
status = remove(file);
}
void renamefile(char* old, char* new){
int ret;
ret = rename(old, new);
if(ret == 0) {
printf("%s renamed to %s\n", old, new);
}
else {
printf("Error: unable to rename %s\n", old);
printf("NO %s", strerror(EACCES));
}
}
char *replace_str(char *str, char *orig, char *rep)
{
static char buffer[4096];
char *p;
if(!(p = strstr(str, orig)))
return str;
strncpy(buffer, str, p-str);
buffer[p-str] = '\0';
sprintf(buffer+(p-str), "%s%s", rep, p+strlen(orig));
return buffer;
}
void replaceline(char* path, char* patternoo, char* replacearoo){
char buff[BUFSIZ]; // the input line
char newbuff[BUFSIZ]; // the results of any editing
char pattern[200];
strcpy(pattern, patternoo);
char replace[200];
strcpy(replace, replacearoo);
FILE *in, *out;
char newstr[200];
//getbases
char basec[200];
char dname[200];
int found = 0;
strcpy(basec, path);
strcpy(dname, dirname(basec));
strcat(dname, "/loot");
in = fopen( path, "r" );
out= fopen( dname, "w" );
while ( fgets( buff, BUFSIZ, in ) != NULL ) {
if ( strstr( buff, pattern ) != NULL ) {
//THIS IS WHERE WE DO THE THING
strcpy(newbuff, replace_str(buff, pattern, strcat(replace,pattern)));
found = 1;
} else {
strcpy( newbuff, buff );
printf("nothin to do\n");
}
fputs( newbuff, out );
fclose( in );
fclose( out );
delete(path); // delete original
renamefile(dname, path); //the temp is now new
}
if(found == 0){
fclose( in );
fclose( out );
}
}
void recursiveWalk(const char *pathName, int level) {
DIR *dir;
struct dirent *entry;
if (!(dir = opendir(pathName))) {
fprintf(stderr, "Could not open directory\n");
return;
}
if (!(entry = readdir(dir))) {
fprintf(stderr, "Could not read directory\n");
return;
}
do {
char path[1024];
int len = snprintf(path, sizeof(path)-1, "%s/%s", pathName, entry->d_name); // get depth
if (entry->d_type == DT_DIR) { // found subdirectory
// skip hidden paths
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
recursiveWalk(path, level + 1);
}
else { // files
fprintf(stdout, "%s \n", path); // HERE!!!!!!!!!!!
replaceline(path,"dime", "lime");
}
} while ((entry = readdir(dir)));
closedir(dir);
}
int main(int argc, char* argv[]){
// replaceline("./toast/nodime","dime", "lime");
recursiveWalk("./toast", 0);
return 0;
}
最佳答案
在功能上:replaceline()
我怀疑代码正在关闭文件,并尽早删除源文件。
建议循环读/修改/写,直到文件结尾,
然后关闭文件并删除源文件。
如果文件包含要替换的字符串,则循环中的后续遍历将尝试从关闭的文件中读取。
建议在读取完整个文件后才关闭,删除,重命名文件。退出while循环后
08-25 01:57