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语言 文件方面 段错误 核心已转储 以及字符串查找删除的问题的主要内容,如果未能解决你的问题,请参考以下文章
Linux:段错误(核心已转储) Segmentation fault (core dumped)(在Linux上如何得到一个段错误的核心转储)(笔记)(未完成,暂停)