2015-09-10 34 views
-4

我试图编译使用该程序:“的sprintf” 使用Visual Studio提高例外2013

  • 的Visual Studio 2013
  • WATCOM

在WATCOM它编译和运行完美。

在Visual Studio上,第二个sprintf引发了一个异常。

计划:

#define _CRT_SECURE_NO_WARNINGS 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main(){ 
//-------------------------------------------------------// 
    char  *filename = 0; 
    filename = (char *)malloc(100* sizeof(char)); // allocate 

    sprintf(filename, "Test");      // write to string ok 

    filename = "Test";        // write to string 

    sprintf(filename, "Test");      // write to string fails VisualStudio2013. 

    getchar(); 
} 

我不明白发生了什么。有人可以解释吗?

+2

你真的可以在这里添加异常吗? – fk2

+3

'filename =“Test”;''''sprintf(filename,“Test”);''后不能写静态分配的存储。 –

+3

*在Watcom上编译和运行完美。*它不能“完美”运行,除非“完美”意味着程序没有崩溃。您正在通过覆盖'malloc'返回的指针来创建内存泄漏。 – PaulMcKenzie

回答

2
filename = "Test"; // Make filename point to a constant 

sprintf(filename, "Test"); // try to modify what filename points to 

你不能修改一个常量,这就是它们的常量。

4

TL; DR:

filename = "Test"; 

的​​内容没有写入filename。它使它指向字符串字面意思​​。


说明:

char  *filename = 0; 

filenameNULL

filename = (char *)malloc(100* sizeof(char)); 

filename现在指向分配的存储器段的开始(假设malloc成功地分配存储器)。

sprintf(filename, "Test"); 

5个时隙开始与所述一个filename当前指向填充的​​字符。换句话说,​​写入filename

filename = "Test"; 

其中filename点被改变的位置和现在,它指向的字符串文字​​(具体地,它指向的字符串文字​​的第一个字符的地址)。因此,如果您不知道分配的内存会导致内存泄漏(并且您不知道分配的内存是否丢失),那么您将失去分配内存的空间。

sprintf(filename, "Test"); 

上面sprintf写入​​入位置filename点。

但是,字符串文字是不可改变的,这意味着它们不能被改变。尝试更改字符串文字的内容会导致未定义的行为。所以,写入该位置会改变字符串文字filename的内容以指向未定义的行为。