本文介绍了为什么我们存储字符串中的字符指针,例如fopen()函数;?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想更深入的以下行:

 的char *文件名=file.txt的;

这我这样做的时候,我们使用 fopen()函数;

我的问题是:


  1. 文件名应该持有一个字符的地址(适用于酷睿2 36位)。为什么我们要放一个'字符串的呢?


  2. 为什么,因为你可能会被存储能够永远存在的地址,编译器会不会产生一个错误(S)?



解决方案

The expression char* filename="file.txt"; is a valid expression. Reason is type of a string literals in C is char[N] that can easily decay into char*, and char[N] and char* are compatible. Hence you can assign string address to a char* pointer variable like you are doing in this expression.

Please read below three points:

  • Its a valid address:

No, in the expression char* filename="file.txt";, filename is assigned a valid address. Its conceptually something like (assuming address starts with 21):

filename   21  22   23  24  25  26  27  28  29
+---+     +------------------------------------+
|21 |---> |'f'|'i'|'l'|'e'|'.'|'t'|'x'|'t'|'\0'|
+---+     +------------------------------------+

filename pointing to string, a valid address.

and It don't gives any error or warning: try below code example:

example-1:

#include<stdio.h>
int main(int argc, char **argv){
    char* filename = "filename.txt";
    printf("%s", filename);
    return 0;
}

Compile it:

:~$ gcc y.c  -Wall -pedantic
~$ ./a.out
filename.txt

No error and waring, its compiling and executing perfectly.

Regarding you comment to my answer:

Strings in C are bit complex data-structured then simple value variables like int, char, float.

In case of basic data-types:

But for strings, when you do:

  char* filename = "filename.txt";

Then you are actually assigning address of string "filename.txt" to char* pointer variable filename.

Whereas if you do:

  char filename[] = "filename.txt";
      //        ^ notice [] in declaration

Then you are assigning string "filename.txt"; to an array of char filename[], here filename type is char[].

To learn about more deferences in both declarations read: What does sizeof(&arr) return?

A string literal may give you value or address dependences in what context you use it. for example try: printf(" address: %p, value: %s", "Hello", "Hello");

  • Compiler do not validates address but check syntax.

The compiler is not responsible to validate that a address is legal. Compiler transplants code and checks syntax errors(for example uncompilable type mismatch). Suppose if you assign a fake address to a pointer it won't give you a waring (if you correctly type casts address). Consider the below example:

example-2:

#include<stdio.h>
int main(int argc, char **argv){
    char* filename = "filename.txt";
    char* ptr = (char*)0x020202;
    printf("%s %s\n", filename, ptr);
    return 0;
}

Compile:

$ gcc y.c  -Wall -pedantic

And it will not generates any error or waring. Because syntactically all is fine and valid.
(Whereas ptr assigned a fake address that may not exists).

  • Invalid address causes Undefined behavior at runtime

Well, its fine to compile example-2 code where ptr is assigned a a fake address, and compiler don't generates any error/warning even with stick checking flags options: -Wall -pedantic.

But executing this code is wrong. It try to access memory address assigning to ptr in printf statement, And the program will behave abnormally (at different executing instance). In C-Language standard its called: Undefined behavior.

When you executes this code OS (but not compiler) detects memory right violation by a process -- An invalid access to valid memory gives: SIGSEGV And access to an invalid address gives: SIGBUS. This may cause process terminate/crash with some segmentation fault and coredump.

To learn and know what can be happen when you access illegal memory read: strcat() implementation works but causes a core dump at the end.

这篇关于为什么我们存储字符串中的字符指针,例如fopen()函数;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 21:47
查看更多