使用循环范围变量写入内存并从外部访问它

时间:2013-08-06 18:04:48

标签: c string memory

背景:


这一切都始于我朋友用文件写的程序。

跳过其他细节,我正集中在实际吸引我注意力的地方。

  1. 文件中有文本需要提取为字符串。
  2. 琴弦可能有不同的长度。
  3. 为了达到这个目的而不花费额外的一个字节,他使用了动态内存分配。他首先计算了大小,然后使用malloc创建了一个足够大小的字符串,然后将字符插入到目标字符串中。
  4. 这很好,但我倾向于考虑是否有另一种方法将字符存储在字符串中而没有任何额外的字节。

    我参加了以下计划:

    代码:


    / *为简单起见,我在这里使用了另一个字符串“c”而不是文件,需要复制数据。将ch视为File中的读取字符。

    # include <stdio.h>
    # include <string.h>
    
    void main()
    {
    char *s,*p;
    char c[4] ="abc";
    
    char q[2] = "";
    s=q;
    
    int i;
    for(i=0;c[i]!='\0';i++)
    {
        char ch = c[i];
        int len = strlen(s);
        char p[len+2];
        strcpy(p,s);
        p[len]=ch;
        p[len+1]='\0';
        printf("%s\n",p);
        s=p;
    }
    char t[strlen(s)+1];
    strcpy(t,s);
    
    printf("%s\n",t);  //EDIT for understanding: If I print s here it prints garbage, 
                              but if I see the value of s through debugger, it gives
                              correct value?
    }
    

    理解:


    1. 字符串p的作用域为for循环,对于每次迭代,我们都会得到一个新的定义。
    2. 字符串的起始地址保存到变量s,这就是为什么即使代码超出范围也可以访问内存,这用于在遇到新字符时决定字符串的大小。
    3. 问题:


      1.如果我的理解是正确的,那么就会缺少某些东西。我这样说是因为不是strcpy s到t和打印t(这给出了正确的O / P),如果我直接尝试打印s,它会打印垃圾。我不确定这种行为?

      2.此程序中是否存在内存损坏的可能性?

      P.S。:我知道多个strcpy()过度杀戮,因此程序没有优化,只是要求这个问题来理解这种行为。

2 个答案:

答案 0 :(得分:1)

一旦变量的生命周期结束,编译器就可以根据需要自由重用内存。当你创建一个“new”p(下一次循环循环,循环结束后)保留指向“old”p的指针并不能保证完全正常工作。我不希望这项工作可靠,很可能旧的和新的ps最终可能重叠。

无论是使用strcpy还是其他任何技术,与简单使用malloc和偶尔重新分配的情况相比,数据的连续混乱将花费很多。

答案 1 :(得分:0)

main中,s和p被定义为指针:char *s, *p稍后在for循环之后你会询问打印和获取垃圾,因为s是指针而printf正在尝试要打印该地址,请使用:printf("%p", s);打印存储在s中的地址或printf("%c", *s);打印s指向的字符。

在for循环中,您定义了一个名为p[len+2]的变量,此定义会影响main中的声明。一般来说,这是一种不好的做法。您是否真的要1)定义第二个版本的p或2)您是否要在p指向的位置存储信息。

如果1)将p重命名为其他内容,那么你的bug就会很明显;如果2)为p分配一些存储指向,然后从你的for循环填充它。

希望我理解你的意图并希望这会有所帮助。