为什么块中分配的数组在块结束后仍然存在?

时间:2014-04-18 17:43:07

标签: c

一旦函数退出,就会释放本地数组的内存吗?那么为什么当我使用一个块代替它时呢?

int main(int argc, char **argv){
    char *s2;

    {
        char s[] = "testing";
        s2 = s;
    }

    printf("%s\n", s2);
    return 0;
}

4 个答案:

答案 0 :(得分:2)

由实施决定。唯一确定的事情是s 无法保证无法保证仍可访问,但当然也可以。

只是未定义的行为。因此,不要依赖它。

答案 1 :(得分:0)

它实际上不存在。 printf的结果未定义。 似乎按预期工作 ,因为您的特定编译器并未保护您不这样做,并且该内存的内容尚未在其他应用程序中设置和更改。

即使是s2指针,数组s []的内容也不再有效。

答案 2 :(得分:0)

释放一大块内存并不意味着写入的内容被删除/清除。实际上,您的程序会调用未定义的行为 访问以前释放的内存块是新手和有经验的程序员的许多内存错误的原因。

答案 3 :(得分:0)

当记忆是"免费"它只是意味着它可以再次使用。存储在那里的任何数据将保留,直到再次使用该部分内存。但是如果你要写更复杂的代码,调用一些函数,传递一些变量,分配一些变量......你会看到这个内存被重用。

这是您在使用C编码时必须考虑的常见问题。例如,假设您正在编写一个返回字符串值的函数。您需要一些空间来存储该字符串在函数退出后仍然有效。您不能将它作为局部变量分配给函数(或块,就像您在问题中所做的那样),因为在您的函数期间,该内存仅属于您。

例如:

char *func1() {
  mydata = "here is the data";

  /* NO! */
  return mydata;
}

int main(int argc, char**argv) {

  char *s = func1();
  /* s now contains a pointer to where mydata WAS but this memory is out of scope */
  /* at some point it will be written over with something else and your program   */
  /* will break */
}

那么,我们怎么写呢?一个常见的解决方案是:

char *func1(char *s, int len) {
  mydata = "here is the data";

  /* copy the data into the provided memory.. but if it is too short, */
  /* make sure the string is null terminated                          */
  strncpy(s, mydata, len);
  s[len-1] = 0;    

  return s;
}

int main(int argc, char**argv) {
  /* allocate at least as much memory as we will need */
  char mymem[100];

  /* pass pointer to mymem into func1, and tell func1 how much space it has */
  char *s = func1(mymem, sizeof(mymem));
}

有道理吗?你也可以使用malloc()和free(),但这个问题太多了......