Cで犯す4つの簡単な間違い

読者の皆様、こんにちは。この投稿では、Cでプログラミングするときに最も一般的な間違いを回避する方法を学びます。





行末文字の誤った使用(null文字 '\ 0')

次のコードを検討してください。





#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv){
	char *str = "Hello \0 world!\n";
  int l = strlen(str);
  printf("Str: %s\nLength: %d\n", str, l);
}
      
      



このコードでは、次の結果が得られます





Str: Hello 
Length: 6
      
      



.. "Hello " "world!\n" , , . . :





while((cur_symbol = *++str) != '\0') process_symbol(cur_symbol);
      
      



'\0'



strlen 6. . , printf %s str , .





, . ? , , . .. char , , , long int char[], , char * ptr. , 32- , - (, 232 ). char , - .





memcpy :





memcpy(void *dest, const void *source, size_t n);
      
      



n- , source, , dest.





, :





#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv){
    char *msg = malloc(20);
    long int l = 16;
    memcpy(msg, &l, 4);
    char *c1 = "Hello world!!!\n"; /* length 15 symbols + 1 '\0' symbol */
    memcpy(msg + 4, c1, 16);
    
    
    long int l2 = 0;
    memcpy(&l2, msg, 4);
    char *c2 = malloc(l2);
    memcpy(c2, msg + 4, l2);
    
    
    printf("Str: %s\nLength: %d\n", c2, l2);
    
    free(msg);
    free(c2);
}
      
      



. 20 . 4 , 16 . l . memcpy msg. 4 msg . c1, . 16, '\0'



. , memcpy, 5 msg , c1, , , .. l.





, , : l2 c2. C memcpy l2 msg. c2 msg, msg, , l2, .





, printf, l2 c2. ,





Str: Hello world!!!

Length: 16
      
      



, . memcpy , char.





memcpy: , , . , , .





, .

:





char *mystr = "This is my string\n";
mystr = mystr + 13;
*mystr = 'u';
      
      



Segmentation Fault. , mystr . , .text , . , , mystr , .





malloc, , . - , , . mystr 19 .





free

malloc calloc , .. , , . main, exit , , , , , (, , _exit, , ).





, ? , , , . free , (.. ) :





char *s1 = malloc(255);
process(s1);
free(s1);
      
      



, process s1. process , .. 255 , s1. s1, . process :





process(char *s);
      
      



, free :





s1 = s1 + 1;
      
      



s1, , s1 1 . free, s1 , .





: , , free, .





, , , :





void process_person(struct Person *p){
	char name[] = "El Barto\0";
  p->name = name;
  printf("Person name: %s was initiated\n", p->name);
}
      
      



Person, :





struct Person {
	char *name;
};
      
      



, main, , Person, (name) process_person:





/* in main() body */
struct Person p1;
process_person(&p1);
sleep(2);
printf("Person name is: \"%s\"\n", p1.name);
      
      



main, Person , main. process_person, , . , , process_person. name. ( ) name, . , process_person, , 2 . ( sleep). sleep <unistd.h> :





unsigned int sleep(unsigned int seconds);
      
      



2 , , , p1. .. , . :





Person name: El Barto was initiated 
Person name is: "
      
      



, , , - process_person p1.name , \'0'



.





, , , - :





Person name: El Barto was initiated
Person name is: "ElBar2#1"
      
      



, :





" , ."





.. . .. f, () f. , . , g f, g , f, , , f, g.





もちろん、エラーが発生した場合、コードの制御フローを変更することは可能です。ある機能の本体から別の機能の本体への移行。この場合、このような状況では、グローバル関数でグローバル変数を使用できます。





PSこの投稿では、4種類のエラーのみが考慮されました。上記以外にも頻繁に発生する可能性のあるエラー状況があります。








All Articles