A difference between array and pointer in ANSI C

What confuses me:

Let's begin with a snippet at page 104 of The C Programming Language(Second Edition):

A snippet from *The C Programming Language(Second Edition)*

From this snippet we can see,it is illegal to evaluate c expressions like:

    char *pmessage = "now is the time";
    printf("%s\n",pmessage);
    pmessage[0] = 'p';
    printf("%s\n",pmessage);

Because the "now is the time" is constant string

But it is totally ok with the c complier in my Windows:

The result in Windows

That makes me confused.

Then I put the same codes in Ubuntu:

The result in Ubuntu

The codes are complied successfully.But something wrong happened when I run the complied program.It says:Segmentation fault (core dumped)

The result in Windows doesn't correspond with what the book says,it seems to indicate the c compiler of Microsoft doesn't conform to the ANSI C standard at this place. I guess the c compiler of Microsoft doesn't let the pmessage point to a constant string.My confussion got relieved.

What is the difference between array and pointer?

To figure out what does "Segmentation fault" mean,I found an answer in Stackoverflow,which also illustrates the difference between array and pointer very well:

There is nothing inherently wrong with using pointers as arrays, unless those pointers point to constant data (and string literals are constant data). Although semantically incorrect, in the old days of no memory protection, pmessage[0] = 'n'; would have actually worked with unpredictable results (e.g. affecting all occurrences of the same literal within the program). On modern operating system this could not happen because of the memory protection in place. String literals and other constants are put in so-called read-only sections of the executable and when the executable is loaded in memory in order to create a process, the memory pages that contain the read-only sections are made to be read-only, i.e. any attempt to change their content leads to segementation fault.

char amessage[] = "now is the time";

is really a syntactic sugar for the following:

char amessage[] = { 'n','o','w',' ','i','s',' ','t', 'h','e',' ','t','i','m','e','\0' };

i.e. it creates an array of 16 characters and initialises its content with the string "now is the time" (together with the NULL terminator).

On the other hand

char *pmessage = "now is the time";

puts the same string data somewhere in the read-only data and assigns its address to the pointer pmessage. It works similar to this:

// This one is in the global scope so the array is not on the stackconst 
const char _some_unique_name[] = "now is the time";
//the 'const' is added by Vincent Ge,not in the origin edition of this answer
char *pmessage = _some_unique_name;

_some_unique_name is chosen so as to not clash with any other identifier in your program. Usually symbols that are not permitted by the C language, but are ok for the assembler and the linker, are used (e.g. dots like in string.1634).

You can change the value of a pointer - this will make it point something else, e.g. to another string. But you cannot change the address behind the name of an array, i.e. amessage will always refer to the same array storage that was allocated for it in first place.

You can refer to individual elements of each string using amessage[i] or pmessage[i] but you can only assign to the elements of amessage as they are located in the read-write memory.

Reference: http://stackoverflow.com/questions/11691324/forbiddens-in-string-literals-in-c

Experiments afterwards:

Although semantically incorrect, in the old days of no memory protection, pmessage[0] = 'n'; would have actually worked with unpredictable results (e.g. affecting all occurrences of the same literal within the program).

String literals and other constants are put in so-called read-only sections of the executable.

These two sentences indicates that all the occurrences of the same string will access the same memory address,and this address is remote from the address of local variables.This is my assumption 1.

Base on my guessing thatthe c compiler of Microsoft doesn't let the pmessage point to a constant string,I guess pmessage and amessage will have nearby memory address on Windows.This is my assumption 2.

To confirm my assumptions I wrote the following codes:

    char amessage1[] = "array:now is the time";
    char amessage2[] = "array:now is the time";
    char *pmessage1 = "pointer:now is the time";
    char *pmessage2 = "pointer:now is the time";
    printf("%s Address:%X\n",amessage1,amessage1);
    printf("%s Address:%X\n",amessage2,amessage2);
    printf("%s Address:%X\n",pmessage1,pmessage1);
    printf("%s Address:%X\n",pmessage2,pmessage2);

Result in Windows:

Result in Windows

Result in Ubuntu:


Result in Ubuntu

Assumption 1 is confirmed,but assumption 2 not.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • **2014真題Directions:Read the following text. Choose the be...
    又是夜半驚坐起閱讀 11,111評(píng)論 0 23
  • PLEASE READ THE FOLLOWING APPLE DEVELOPER PROGRAM LICENSE...
    念念不忘的閱讀 13,660評(píng)論 5 6
  • 期盼良久的《誅仙》,魂?duì)繅?mèng)縈,近乎十年,我還在當(dāng)年的路口等你,終于等到了你! 你卻不復(fù)當(dāng)年模樣,現(xiàn)在你叫《青云...
    江藍(lán)藍(lán)閱讀 1,144評(píng)論 0 1
  • 禮是中華文化的核心概念之一,錢穆先生曾說(shuō)過(guò),中國(guó)文化說(shuō)到底是一個(gè)字,就是禮,禮在中華文化中的重要性不言而喻。周公制...
    sunny321225閱讀 12,965評(píng)論 9 31
  • 檢視閱讀練習(xí)~2.9 看包裝## 標(biāo)題 : 習(xí)慣的力量 我們?yōu)槭裁磿?huì)這樣生活,那樣工作 作者:[美] 查爾斯·杜希...
    kcalm閱讀 159評(píng)論 0 0

友情鏈接更多精彩內(nèi)容