C语言 文件方面 段错误 核心已转储 以及字符串查找删除的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言 文件方面 段错误 核心已转储 以及字符串查找删除的问题相关的知识,希望对你有一定的参考价值。

这部分是 文件 删除功能的调用,想实现从一个文件中读取内容到缓冲区,再在这个缓冲区找到需要删除的字符串,(那个字符串已存入r【10】字符数组)删除修改后写回去。有些变量定义在前面就不贴了,现在的问题就是执行到strcpy时会出错,显示段错误,核心已转储,ubuntu下gcc编译的。还有我的想法删除缓存区的字符串是用strstr找到那个位置,再用几个空格替换,但好像也不是很好,有更好的方法吗?主要还是希望帮我解决一下段错误,核心已转储问题。谢谢。
FILE *fp;
fp=fopen(filename,"r+");
if(!fp)

printf("can't open file!\n");
exit(1);

fgets(buff,200,fp);
int l=strlen(r); //想计算一下要删的字符串的长度,可是没用上。。
char s[]=" "; //用几个空格代替,可以长度控制不了
p=strstr(buff,r); //char *p ,这里是不是表示找到了缓冲区里 要删的字符串了,并指向那个字符串首地址?
strcpy(p,s); //这里有问题,因为我用printf在上面的每一条下都可以输出,在这里停了。。
puts(buff); //这里程序第一次运行,倒是没问题,再一次执行就段错误了。而且buff输入时空的?
fputs(buff,fp);
fclose(fp);

有几个问题:

    文件在读取了你的字符串后,文件指针位置已经到了该字符串后面,如果puts则会在字符串后面输出,比如:文件内容是aaaa\\nbbbb\\ncccc\\n,你读到bbbb行后,文件指针指向cccc\\n的首字符,如果puts的话会覆盖cccc\\n。按照设计目的,你应当让文件指针返回字符串bbbb\\n的首字符再输出。

    在输出了覆盖字符串后,还应当将文件后面所有行重新写一遍才行。

    比如文件内容是aaaa\\nbb1bb\\ncccc\\n,如果只删除b1则变成aaaa\\nbbb\\nb\\ncccc\\n,而实际上应当改成aaaa\\nbbb\\nccc\\n。

    用同一个文件实现这个功能时,文件的结束很难截断。

建议如下修改:

    FILE *fp,*tp;
    int l;
    char *p;
    char filename[80] = "a.txt" ;
    char filename1[80] = "b.txt" ;
    char r[] = "abc123" ;
    char buff[256];
    int success = 0;
    if (fp = fopen(filename, "r"))
    
        if (tp = fopen(filename1, "w+"))
        
            l = strlen(r);
            while ( !feof(fp) )
            
                fgets(buff, 200, fp);
                if (p = strstr(buff, r))    strcpy(p, p + l);
                fputs(buff, tp);
            
            fclose(tp);
            success = 1;
        
        else printf("cann't open target file!\\n");
        fclose(fp);
     else printf("can't open file!\\n");
    if (success) remove(filename); rename(filename1, filename);
【测试】

原a.txt内容为:

abcdefghijklmn
1234567890
a1a2abc123a4a5a6
b1b2b3b4b
ccccc
运行程序后为:

abcdefghijklmn
1234567890
a1a2a4a5a6
b1b2b3b4b
ccccc

注意:原a.txt文件中最后一行后面不换行结束。

追问

实在很感谢你热心的回答!当时也发现问题出在缓冲区的读取方面,做了修改后解决了问题了,9点20左右就选择了最佳回答,可能你之前看到了就帮忙去测试了,你回答的的确更加有针对性,直接找出了问题所在,很厉害,也很不好意思在你之前已经把分给了别人,你们都很热心,再次说声抱歉和谢谢!

参考技术A p=strstr(buff,r); //char *p ,这里是不是表示找到了缓冲区里 要删的字符串了,并指向那个字符串首地址?

你的理解没错,不过有个前提:确实能找到。如果找不到就会返回0x0,你后面strcpy就会出错。

另外,这句话之后p指向buff中r首次出现的地方,换言之p在buff中间某个位置。
如果p在buff靠后的位置上,然后s又比较长,strcpy(p, s);(这里实际上是将s拷贝到buff中某个位置)就会导致buff最后一个字节后面的内存被意外修改。
既然是linux下,建议使用strncpy;还有strstr返回值要判断一下是不是0x0再使用。

上述均为猜测,具体定位需要知道p=strstr(buff,r);后p的输出,buff的大小,还有s的值。如果还有问题请追问。

PS:直接从一个已有文件中删除某几个字节是不可能的。因为文件在硬盘上是连续存储的,不可能删掉一个字节然后后面的内容自动前移。要实现这个功能只有使用临时文件:将新的整个文件输出到临时文件中,最后删除源文件,将临时文件重命名为源文件的名字。本回答被提问者采纳
参考技术B 如果p在buff靠后的位置上,然后s又比较长,strcpy(p, s);(这里实际上是将s拷贝到buff中某个位置)就会导致buff最后一个字节后面的内存被意外修改。
既然是linux下,建议使用strncpy;还有strstr返回值要判断一下是不是0x0再使用。

上述均为猜测,具体定位需要知道p=strstr(buff,r);后p的输出,buff的大小,还有s的值。如果还有问题请追问。
参考技术C 在linux下有个方法可以快速定位是哪里出错.
[利用core dump文件]
1.设置生成的core文件大小
$ulimit unlimited #设置文件大小为无限
2.
# echo “/log/History/core.%e.%p” >/proc/sys/kernel/core_pattern #这里是用root权限才能修改! core文件放在/log/History/下

3.调试生成出来的core文件
$ gdb ./coreDump core.11531

可以看到如下信息:
Program terminated with signal 11, Segmentation fault.
#0 0x00000000004004c2 in main () at coreDump.c:6
6 *null_ptr = 10; //对空指针指向的内存区域写,会发生段错误
(gdb)

希望对你有帮助,如果你是Linux平台的话

段错误 核心已转储尝试解决

1.在进行

gdb python
r XX.py
where

调试时,报出以下错误:

1)每次运行都开38个线程,是否是线程超载[New Thread 0x7ffff2fd2700 (LWP 7415)]

[New Thread 0x7ffff27d1700 (LWP 7416)]
[New Thread 0x7fffeffd0700 (LWP 7417)]
[New Thread 0x7fffeb7cf700 (LWP 7418)]
[New Thread 0x7fffe8fce700 (LWP 7419)]
[New Thread 0x7fffe67cd700 (LWP 7420)]
[New Thread 0x7fffe3fcc700 (LWP 7421)]
[New Thread 0x7fffe17cb700 (LWP 7422)]
[New Thread 0x7fffdefca700 (LWP 7423)]
[New Thread 0x7fffdc7c9700 (LWP 7424)]
[New Thread 0x7fffd9fc8700 (LWP 7425)]
[New Thread 0x7fffd77c7700 (LWP 7426)]
[New Thread 0x7fffd4fc6700 (LWP 7427)]
[New Thread 0x7fffd27c5700 (LWP 7428)]
[New Thread 0x7fffcffc4700 (LWP 7429)]
[New Thread 0x7fffcd7c3700 (LWP 7430)]
[New Thread 0x7fffcafc2700 (LWP 7431)]
[New Thread 0x7fffc87c1700 (LWP 7432)]
[New Thread 0x7fffc5fc0700 (LWP 7433)]
[New Thread 0x7fffc37bf700 (LWP 7434)]
[New Thread 0x7fffc0fbe700 (LWP 7435)]
[New Thread 0x7fffbe7bd700 (LWP 7436)]
[New Thread 0x7fffbbfbc700 (LWP 7437)]
[New Thread 0x7fffb97bb700 (LWP 7438)]
[New Thread 0x7fffb6fba700 (LWP 7439)]
[New Thread 0x7fffb47b9700 (LWP 7440)]
[New Thread 0x7fffb1fb8700 (LWP 7441)]
[New Thread 0x7fffaf7b7700 (LWP 7442)]
[New Thread 0x7fffacfb6700 (LWP 7443)]
[New Thread 0x7fffaa7b5700 (LWP 7444)]
[New Thread 0x7fffa7fb4700 (LWP 7445)]
[New Thread 0x7fffa57b3700 (LWP 7446)]
[New Thread 0x7fffa2fb2700 (LWP 7447)]
[New Thread 0x7fffa07b1700 (LWP 7448)]
[New Thread 0x7fff9dfb0700 (LWP 7449)]
[New Thread
0x7fff9b7af700 (LWP 7450)] [New Thread 0x7fff98fae700 (LWP 7451)] [New Thread 0x7fff967ad700 (LWP 7452)] [New Thread 0x7fff93fac700 (LWP 7453)]

 

2)现在报出:

ERROR (theano.gpuarray): Could not initialize pygpu, support disabled
。。。
  File "pygpu/gpuarray.pyx", line 658, in pygpu.gpuarray.init
  File "pygpu/gpuarray.pyx", line 587, in pygpu.gpuarray.pygpu_init
GpuArrayException: cuDeviceGet: CUDA_ERROR_INVALID_DEVICE: invalid device ordinal

先不解决这个,先尝试测试一下:

发现,在import keras,也会报上述同样的错误!

 conda install mkl
conda install mkl-service
#使用以上两句均显示:
# All requested packages already installed.

conda install blas

 依旧不可以导入keras包。

 3)将原有的conda环境删除,又新创建了环境,用conda安装了mkl之后,尝试import keras之后,仍然报错:

Using Theano backend.
~/lib/python2.7/site-packages/theano/gpuarray/dnn.py:184: UserWarning: Your cuDNN version is more recent than Theano. 
If you encounter problems, try updating Theano or downgrading cuDNN to a version >= v5 and <= v7. warnings.warn("Your cuDNN version is more recent than " ERROR (theano.gpuarray): Could not initialize pygpu, support disabled Traceback (most recent call last): File "~/lib/python2.7/site-packages/theano/gpuarray/__init__.py", line 227, in <module> use(config.device) File "~/lib/python2.7/site-packages/theano/gpuarray/__init__.py", line 214, in use init_dev(device, preallocate=preallocate) File "~/lib/python2.7/site-packages/theano/gpuarray/__init__.py", line 99, in init_dev **args) File "pygpu/gpuarray.pyx", line 658, in pygpu.gpuarray.init File "pygpu/gpuarray.pyx", line 587, in pygpu.gpuarray.pygpu_init GpuArrayException: cuDeviceGet: CUDA_ERROR_INVALID_DEVICE: invalid device ordinal

在我的.theanorc配置文件中,是这么写的:

[global]
floatX = float32
device =cuda1

 

尝试去掉cuda编号?居然成功了!

Using Theano backend.
~/.conda/envs/xhs/lib/python2.7/site-packages/theano/gpuarray/dnn.py:184: UserWarning: Your cuDNN version is more recent than Theano.
If you encounter problems, try updating Theano or downgrading cuDNN to a version >= v5 and <= v7. warnings.warn("Your cuDNN version is more recent than " Using cuDNN version 7201 on context None Mapped name None to device cuda: GeForce GTX 1080 Ti (0000:03:00.0)

 

接下来尝试解决 上述的用户警告。

由于theano已经是1.0.4最新版本,无法再进行更新,只能尝试将cuDNN版本降级。

但是使用conda list查看所有安装的包:

cudnn                     6.0.21                cuda8.0_0    https://mirrors.tuna.tsinghua.edu.cn/a
#尝试此命令查看pygpu是否可用
DEVICE="cuda" python -c "import pygpu; pygpu.test()"

 

出现以下问题:https://github.com/Theano/Theano/issues/6420

此帮助里说,如果不是使用多个GPU可以忽略test_collectives error。

#尝试以下,
python test_gpu.py
~/.conda/envs/xhs/lib/python2.7/site-packages/theano/gpuarray/dnn.py:184: UserWarning: Your cuDNN version is more recent than Theano. If you encounter problems, try updating Theano or downgrading cuDNN to a version >= v5 and <= v7.
  warnings.warn("Your cuDNN version is more recent than "
Using cuDNN version 7201 on context None
Mapped name None to device cuda: GeForce GTX 1080 Ti (0000:03:00.0)
[GpuElemwise{exp,no_inplace}(<GpuArrayType<None>(float32, vector)>), HostFromGpu(gpuarray)(GpuElemwise{exp,no_inplace}.0)]
Looping 1000 times took 0.192847 seconds
Result is [1.2317803 1.6187935 1.5227807 ... 2.2077181 2.2996776 1.623233 ]
Used the gpu

 

发现其使用的cudnn版本是7.2,明明是6.0但是却调用了7.2?

查看cuda的版本信息发现:

nvcc -V

nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2017 NVIDIA Corporation
Built on Fri_Sep__1_21:08:03_CDT_2017
Cuda compilation tools, release 9.0, V9.0.176

 

test_collectives error

以上是关于C语言 文件方面 段错误 核心已转储 以及字符串查找删除的问题的主要内容,如果未能解决你的问题,请参考以下文章

调试Go语言的核心转储(Core Dumps)

段错误(核心已转储)的原因

Linux:段错误(核心已转储) Segmentation fault (core dumped)(在Linux上如何得到一个段错误的核心转储)(笔记)(未完成,暂停)

linux下,gcc提示“段错误 (核心已转储)”,ubuntu刚上手不大会用,谁说一下是什么问题

Ubuntu20.04出现段错误核心已转储问题解决方案

段错误 核心已转储尝试解决