ZqrFerrari
努力学习,开心生活

1.在C++ 程序中调用被 C编译器编译后的函数,为什么要加 extern “C”?
  答:C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的名字与C语言的不同。假设某个函数的原型为: void foo(int x, int y);该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。由于编译后的名字不同,C++程序不能直接调用C 函数。所以C++提供了C连接交换指定符号extern“C”来解决名字匹配问题。

 

2.考察内存

void GetMemory(char *p)
{
  p 
= (char *)malloc(100);
}
void Test(void
{
  char *str = NULL;
  GetMemory(str);
  strcpy(str, 
"hello world");
  printf(str);
}

请问运行Test函数会有什么样的结果?
  答:程序崩溃。函数参数都是局部变量,改变这些参数的值不会影响调用函数中的值。局部变量被存储在栈中,函数返回时,栈被自动清空。malloc分配的内存不会被自动释放,p指向自由存储区中的内存块,离开该指针的作用域时,该内存块不会被自动归还给自由存储区。因为GetMemory并不能传递动态内存,Test函数中的 str一直都是 NULL。strcpy(str, "hello world");将使程序崩溃。

char *GetMemory(void)
{
  
char p[] = "hello world";
  
return p;
}
void Test(void)
{
  
char *str = NULL;
  str 
= GetMemory();
  printf(str);
}

请问运行Test函数会有什么样的结果?
  答:可能是乱码。因为GetMemory返回的是指向“栈内存”的指针,该指针的地址不是 NULL,但其原现的内容已经被清除,新内容不可知。p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序员常犯的错误,其根源在于不理解变量的生存期。

void GetMemory2(char **p, int num)
{
  *= (char *)malloc(num);
}
void Test(void)
{
  char *str = NULL;
  GetMemory(
&str, 100);
  strcpy(str, 
"hello");
  printf(str);
}

请问运行Test函数会有什么样的结果?

  答:(1)能够输出hello (2 )Test函数中也未对malloc的内存进行释放。(3)GetMemory避免了试题1的问题,传入GetMemory的参数为字符串指针的指针,但是在GetMemory中执行申请内存及赋值语句 p = (char *) malloc( num ); 后未判定内存是否申请成功,应加上: if ( *p == NULL ) {     ...//进行申请内存失败处理  }

void Test(void)
{
  char *str = (char *) malloc(100);
  strcpy(str, “hello”);
  free(str);    
if(str != NULL)
{
   strcpy(str, “world”);
    printf(str);
}

请问运行Test函数会有什么样的结果?
  答:篡改动态内存区的内容,后果难以预料,非常危险。因为free(str);之后,str成为野指针,if(str != NULL)语句不起作用。

 

 3.指出以下代码的问题

int main()
{
  
char a;
  
char *str=&a;
  strcpy(str,
"hello");
  printf(str);
  
return 0;
}

   答:没有为str分配内存空间,将会发生异常。问题出在将一个字符串复制进一个字符变量指针所指地址。虽然可以正确输出结果,但因为越界进行内在读写而导致程序崩溃。

 

posted on 2010-07-11 19:59  赵情融  阅读(679)  评论(1编辑  收藏  举报