'Programming/C'에 해당되는 글 22건

  1. 2007.05.08 세그멘테이션 폴트를 줄이자! valgrind (4)
  2. 2007.05.06 c언어로 구현한 mp3 태그(id3v2) 지우기 (6)
  3. 2007.04.09 pointer 를 call by referance 하기 (6)
  4. 2007.03.06 프로세스 갯수 알아내기.. (4)
  5. 2007.02.22 libconfuse 에서 *** glibc detected *** double free or corruption

세그멘테이션 폴트를 줄이자! valgrind

아 몇일동안 한거 헛수고 했다 -_-;

아...

바로전에 포스팅한것도 괜한 삽질이 되어버린..

덕분에 mp3구조랑 비트연산같은거 다시보긴 했지만.... 아아.........;

계속 길을 둘러간다 -_-;

역시 id3lib 가 잘못된게  아니라 내가 잘못 만든거였다...
350     /*full path!*/
351     m_st.mpd_dirpath = "/home/lowid/data/mp3";
352
353     /*file path 합성*/
354     filepath = (char *)malloc(strlen(m_st.mpd_dirpath) + strlen(m_st.filename));
355     sprintf(filepath,"%s/%s",m_st.mpd_dirpath,m_st.filename);
356
357     /*printf("status : %d \nfilename: %s \nplaytime: %d \ntotaltime: %d\n",
358             m_st.status,m_st.filename,m_st.elasped_time,m_st.total_time);*/
359
360     if((hash_address = get_hash_address(filepath,"temp.mp3")) == NULL ){
361         fprintf(stderr,"주소를 얻는데 실패 main 함수\n");
362         exit(1);
363     }
364
365     /*전체 주소를 받아와서 출력한다*/
366     sprintf(lyrics_address,"%s%s",PAGE_ADDRESS,hash_address);
367     /*printf("%s\n",lyrics_address);*/
368
369     contain_lyrics = get_lyrics(lyrics_address);
위에 코드중에서 잘못되어있는게 있었다... 뭘까~?























바로 malloc이 잘못되있다는거...다...
(자세한건 malloc쪽을 보면 알겠지만 2byte만큼 메모리 할당이 부족하다)
valgrind 를써서 겨우 알아냈다... memory leak을 검사할때는 이툴이 참 좋은거 같다..
$valgrind --leak-check=yes -v ./runfile 이렇게 했던거 같다
나도 처음이라 레포트가 출력되긴하는데... 자세히는 모르겠고 내가만든 함수,사용하는 함수에 관해서
에러체크가 되있고 소스코드상의 라인번호가 나온다 그고 보고 고치는..
일단 어디새는곳 라인까지 가리켜주니까 찾기도 쉽고... gdb랑 같이 느므느므 좋은거 같다...
(사실 gdb도 시작한지 몇일 안됐;; )
아아~ 세그멘테이션 폴트 뜰때 정말 이프로그램 쓰면 직방이다 ㅜㅜ
이 프로그램짤때도 무한 세그멘테이션 폴트 때문에 애먹는데........
왜 대체가, 전혀~ 에러를 먹어서는 안되는 함수에서 틀렸다고 나오니... 그쪽에서만 틀린거 찾고 있었는데..
(뭐 gdb에서의 bt,run,명령어 만으로 찾아내기는 무리였을지도 모르겠지만...........)
이녀석쓰니깐 해결 해결~~

Segmentation Fault! 조금이라도 줄여보자...

그리고 세그멘테이션 오류가 나지 않는다고 하더라도,
valgrind를 이용해서
혹시모르는 에러가 발생하기 않도록 권고(?) 하는 바이다....

Trackback 0 Comment 4
  1. Favicon of http://blog.naver.com/khmirage.do BlogIcon 환상경 2007.05.08 11:23 address edit & del reply

    으흐 valgrind까지 쓰시다니 천재!!!
    저도 요즘 gdb로 디버깅하는 법 보고 있는데 어렵더라구요 -_-
    그래서 급할때는 puts("Test!!";) 요걸로 하기는 하는데 후...
    어서 익숙해져야 할텐데~ 요원하네요 -_-

    • lowid 2007.05.08 21:09 address edit & del

      gdb도 저 잘 몰라여.. bt,run,변수값 찍기..
      뭐 이런거 빼고는 다 책보고서 -_-;
      저도 puts("SUB Func Start";); 뭐 이런식으로
      만들어서 자주써요.. #define 후에 #ifdef~#endif로
      해서 그 사이에 저런거 많이 집어놓으면서 씁니다.

  2. Favicon of http://sakuragi.org BlogIcon sakuragi 2007.05.09 00:10 address edit & del reply

    저도 최근에 과제하면서 malloc을 쓰는 경우가 많은데, 세그멘테이션 폴트가 많이 나더군요. 그래서 이제는 세그멘테이션 폴트가 나오면 malloc부터 의심하게 된다는... :)

    • lowid 2007.05.09 12:56 address edit & del

      c는 역시 메모리를 직접다루니까 편리하기도 하지만
      이런 측면에서 보면 (세세히 다 관리해야 하니까)
      좀 복잡하기도 하네요..

c언어로 구현한 mp3 태그(id3v2) 지우기

 지금 삽질하면서 만들고 있는 프로그램이 mp3 태그를 건들여야 할 일이 있어서
id3lib인가 암튼 mp3태그를 건드리는 라이브러리를 썻었는데 그놈아는 자꾸 써먹다보니까 너무 잘 꺼졋다!!!
더 정확하기 말하자면 에러메세지를 좍 뿌리고 죽어버리는 현상이 발생해서 걍 내가 하나 만들어 버렸다..

mp3 파일의 헤더를 읽어서 태그 전체의 크기를 알아낸다
저 쉬프트 연산만 빼면 그다지 어렵지 않은 코드.. 뭐 반복문이나 재귀어떻게 잘 쓰면 짧게 할수도 있을거
같긴한데.. 뭐 얼만큼 길다고.. 겨우 4byte밖에 안되기에 걍 저리 적었다..
그리고..내가좀 멍청해서 도우지 저런식으로 시프트,or연산을 써서밖에 못 나타나겠다...;;
이것에 대해서 잘 아시는분은 댓글 달아주셔도 감사!

모든 mp3파일 에 다 되는건 아니고 "거의 대부분" 이 된다..
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4 #include <fcntl.h>
 5
 6 int main(int argc,char *argv[])
 7 {
 8     int fd;
 9     char buf[10] = {0};
10     int ok = 0;
11
12     if(argc != 2){
13         printf("Usage : %s filename.mp3\n",argv[0]);
14         exit(1);
15     }
16
17     if((fd = open(argv[1],O_RDONLY)) == -1){
18         perror("File Open ERROR");
19         exit(1);
20     }
21
22     /*헤더(10byte)를 읽어온다*/
23     if(read(fd,buf,10) == -1){
24         perror("File Read ERROR");
25         exit(1);
26     }
27
28     if(!(buf[0] == 'I' &&
29         buf[1] == 'D' &&
30         buf[2] == '3')){
31         fprintf(stderr,"mp3 파일이 아니거나 ID3v2 태그를 가진 파일이 아닙니다\n");
32         exit(1);
33     }
34
35     printf("mp3 file : %x %x %x %x\n",buf[6],buf[7],buf[8],buf[9]);
36
37     ok = ((((buf[6] << 21) | buf[7] << 14) | buf[8] << 7) | buf[9]) + 10;
38
39     printf("ID3 태그를 제외한 파일 시작: %x\n",ok);
40 
41     return 0;
42  }
음 일단 애러 처리는 다 해두긴 했는데... 무슨 에러가 있어도 난 책임 안짐 =3=3
그리고 영어 문법에 딴지 걸지 말자 나 작문할줄도 모른다구 ㅜㅜ
그리고 mp3파일 10개정도만 테스트 해봤는데 잘되는............

덧>
:so $VIMRUNTIME/syntax/2html.vim
이렇게 하면 html문서로 저장이 되는군!
알긴 알았지만 이렇게 직접 블로그에 써먹기는 처음..

mp3태그 분석에 대해선 다음 링크를 참조하자
http://www.byungju.com/wiki/wiki.pl?ID3#_1
아니면 kldp에서 번역된 RFC문서를 참고 하셔도 좋으실듯 싶다..

들어오셔서 글을 보셧다면
제발 댓글좀 달아주셈 ㅜㅜ

앗 버그있다..

Trackback 0 Comment 6
  1. Favicon of http://sakuragi.org BlogIcon sakuragi 2007.05.06 16:25 address edit & del reply

    오홍.. 소스를 이쁘게 html 로 바꾸는 건 저도 좀 가져 가야 겠군요. :D

    • lowid 2007.05.07 16:31 address edit & del

      확실히 소스가 색깔느니깐 이쁘네여. 다시봐두..
      가져가세요~

  2. 환상경 2007.05.07 10:44 address edit & del reply

    이런 천재님 !!!!!

    덧붙이는글) 소스 하이라이팅 되게 포스팅하는거 어떻게 하신거에요?
    덧붙이는글1) 덧글은 매번 남기는데요 -_-
    덧붙이는글2) 태그 멋지군요 -_- 망할놈의 id3v2태그 죽어라 !!! 라니요 ㅋㅋㅋ

    • lowid 2007.05.07 16:33 address edit & del

      vi에서 html로 소스 바꾸는 걸루 html태그들을
      복사해서 테터 편집할때 html모드로 바꿔서 붙여넣기 한거에요.
      이런 마이너한 블로그에 매번 덧글 남겨줘서 고마워요~

  3. san 2007.05.08 02:44 address edit & del reply

    와~ 잘보고 가요 ^^

    • lowid 2007.05.08 21:10 address edit & del

      이번 변방에서 까지 행차해주셔서 감사 !
      꾸벅.

pointer 를 call by referance 하기

  1 #include<stdio.h>
  2 #include<malloc.h>
  3
  4 struct choco
  5 {
  6     int a;
  7     int b;
  8     int c;
  9 };
 10
 11 void me(struct choco* *fk)  //main에서 void(?) 넘긴걸 "struct choco *" 형으로 받는다
 12 {
 13     struct choco *abc;
 14     int i;
 15
 16     printf("func call value : %p\n",*fk);
 17     printf("func call momory address : %p \n",fk);
 18      //이 함수가 끝나더라고 malloc의 메모리는 해제되지 않는다..
 19     abc=(struct choco *)malloc(sizeof(struct choco)*3);
 20
 21     abc[0].a=1;
 22     abc[0].b=2;
 23     abc[0].c=3;
 24
 25     abc[1].a=11;
 26     abc[1].b=22;
 27     abc[1].c=33;
 28
 29     abc[2].a=111;
 30     abc[2].b=222;
 31     abc[2].c=333;
 32
 33     for(i=0;i<3;i++)
 34         printf("func pointer memory (struct) value %d : %d %d %d \n",i,abc[i].a,abc[i].b,abc[i].c);
 35
 36     puts("\n");
 37   
 38     *fk=abc; //이게좀 했갈렸다..
 39 }
 40
 41 int main(void)
 42 {
 43     struct choco *po;
 44     int i;
 45
 46     po=NULL;
 47
 48     printf("Before pointer value : %p \n",po);
 49     printf("Before pointer memory address : %p\n",&po);
 50     puts("\n");
 51    
 52     me(&po);    // void로 값을 넘긴다
 53    
 54     printf("After pointer value : %p \n",po); //요값은 아까 struct choco  *abc의 값!
 55
 56     for(i=0;i<3;i++) //당연히 free되지 않았으므로.. .가능 .. 값을 뿌려줌..
 57         printf("After pointer memory (struct) value %d : %d %d %d \n",i,po[i].a,po[i].b,po[i].c);
 58     puts("\n");
 59
 60     //free가 제대로 앙대 ㅜㅜ(일단 패스)
 61     free(po);
 62
 63     return 0;
 64 }

결과
Before pointer value : (nil)
Before pointer memory address : 0xbff28ac8


func call value : (nil)
func call momory address : 0xbff28ac8
func pointer memory (struct) value 0 : 1 2 3
func pointer memory (struct) value 1 : 11 22 33
func pointer memory (struct) value 2 : 111 222 333


After pointer value : 0x804a008
After pointer memory (struct) value 0 : 1 2 3
After pointer memory (struct) value 1 : 11 22 33
After pointer memory (struct) value 2 : 111 222 333



:cw
Press ENTER or type command to continue

더 간단 버전.. 즉 앞에한짓은 뻘짓이라는게 증명됨(??)
  1 #include<stdio.h>
  2 #include<malloc.h>
  3
  4 truct choco
  5 {
  6     int a;
  7     int b;
  8     int c;
  9 }; 
 10
 11 struct choco* me(void)
 12 {
 13     struct choco *abc;
 14     int i;
 15    
 16     abc=(struct choco *)malloc(sizeof(struct choco)*3);
 17    
 18     abc[0].a=1;
 19     abc[0].b=2;
 20     abc[0].c=3;
 21    
 22     abc[1].a=11;
 23     abc[1].b=22;
 24     abc[1].c=33;
 25
 26     abc[2].a=111;
 27     abc[2].b=222;
 28     abc[2].c=333;
 29
 30     for(i=0;i<3;i++)
 31         printf("func pointer memory (struct) value %d : %d %d %d \n",i,abc[i].a,abc[i].b,abc[i].c);
 32        
 33     puts("\n");
 34   
 35     return abc;
 36 }  
 37
 38 int main(void)
 39 {
 40     struct choco *po;
 41     int i;
 42    
 43     po=NULL;
 44    
 45     printf("Before pointer value : %p \n",po);
 46     printf("Before pointer memory address : %p\n",&po);
 47     puts("\n");
 48    
 49     po=me();
 50    
 51     printf("After pointer value : %p \n",po);
 52    
 53     for(i=0;i<3;i++)
 54         printf("After pointer memory (struct) value %d : %d %d %d \n",i,po[i].a,po[i].b,po[i].c);
 55     puts("\n");
 56    
 57     free(po);
 58 }  

어짜피 malloc은 static과 같이 값이 유지되므로 결론적으로
"값만 받아내면 된다" 그래서 사용하는것도 같이 사용..

내가 free를 많이 안해봐서 몰랐는데
구조체 포인터라고 할지라도 그냥 free하고 포인터네임만 쓰면 되는거 같다(위엔,1차원이므로)
그런데 신기하게도(?) free한다음 for문을 돌려서 안에 내용을 확인하면 포인터 네임 위치만 NULL
이 되어있고 나머지 값들은 다 유지한 상태로 되있다 -_-;
딴 프로그램에서도 이런식으로  free를 했길래 위에 free방법이 틀리지 않은거 같은데..
값은 아니네.. 이상함..;;

4,19일 수정
Trackback 0 Comment 6
  1. Favicon of http://blog.naver.com/khmirage.do BlogIcon 환상경 2007.04.10 14:39 address edit & del reply

    천재~!!!

    malloc로 선언했다고 하더라도 함수벗어나면 못쓰게 되는거라 생각했었는데
    아니었었나보군요 -0-
    알면알수록 어려운 C.............

    • lowid 2007.04.11 17:18 address edit & del

      거봐염 쓸수 있잖아요 ~ =3

      하지만 귀찮은건 역시 free해주기..
      (뭐 자동으로 해준다고는 하지만 .그래도..)

  2. Favicon of http://sakuragi.org BlogIcon sakuragi 2007.04.14 17:51 address edit & del reply

    저도 그 free 부분에서 궁금한게.. main 함수가 아닌
    int** func(int **a)
    같은 함수 내부에서 int **b 형태도 선언해서 malloc으로 메모리 할당 한 후에
    그 b를 return 해 버린다면 free 할 기회가 없어진다고 생각 되는데 이때는 어떻게 해야 되는 거죠?
    return 을 받은 녀석을 int **c 라고 가정하면 c 를 free 하면 해결되는 걸까요? -_-;;
    뭐.. 자동으로 해준다고는 하지만요.. 뭔가... ㅜㅡ

    • lowid 2007.04.19 18:22 address edit & del

      걍포인터던 이중포인터던 어짜피 malloc하면 힙(영역이던가?)
      영역에 데이터가 생성(메모리 유지)되므로 값만 받아서 free시켜주면 될듯합니다..
      즉 받아서 (2중포인터로 받았다면)main함수에서 2중포인터 free해주듯이 그func함수에서 리턴받은 값도 마찬가지로 처리하면 될거 같아요..;;(결론적으로 sakuragi님 말대로 될거 같다는)
      (틀릴수도 있으니깐 너무 믿진마시고; )
      덧>다시 작성한 위글이 도움이 될지도.

  3. Favicon of http://blog.naver.com/khmirage.do BlogIcon 환상경 2007.04.16 08:50 address edit & del reply

    garbage collector 최고 ~
    포인터 훼~
    물러가라 포인터~

    • lowid 2007.04.19 00:41 address edit & del

      타도! 포인터!
      (하지만 쓸수 밖에 없다는 orz..)

프로세스 갯수 알아내기..


config파일과 프로세스와의 연계?? 가 필요해서 
혼자서 잡질..
joinc가니가 소스가 있긴하던데..(ps 만들기...)
걍안보고 해봤음.................
덧> 꺽쇠는 문자 망할놈의 태그땜에..

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<dirent.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>
 
#define FALSE 0
#define TRUE !FALSE
#define PROCESS_NAME "myterm"           //찾아낼 프로세스 이름
 
int CharDigit(char *data)               //chk할 문자열을 받는다 다숫자가 마즈면 TRUE else FALSE
{
    while(*data!='\0'){
        if(!isdigit((int)*data)){
            return FALSE;
        }
            data++;
    }
    return TRUE;
}

int main(void)
{
     DIR *op_proc;
     struct dirent *rd_proc;
     int fd;
     char path[50];
     char buf[50];
     char *po;
     int ps_num=0;
 
     if((op_proc=opendir("/proc"))==NULL){      
         perror("디렉토리 열기가 실패했습니다!");
         exit(2);
     }
 
     while((rd_proc=readdir(op_proc))!=NULL){     
 
         if(CharDigit(rd_proc->d_name))  {        //숫자라면
             memset(path,0,sizeof(path));
             sprintf(path,"/proc/%s/status",rd_proc->d_name);
 
             if((fd=open(path,O_RDONLY))==-1){
                 perror("파일 열기 가 실패했습니다!");
                 continue;
             }
 
             read(fd,buf,sizeof(buf));
 
             //파싱..
             strtok(buf,"\n");
             po=strchr(buf,(int)'\t');
             po++;
 
             if(strcmp(po,PROCESS_NAME)==0)
                 ps_num++;
         }
 
     }
 
     printf("프로세스 갯수:%d\n",ps_num);
     return 0;
}
쫌 고쳤는데 컴파일 잘될려나...
Trackback 0 Comment 4
  1. Favicon of http://khmirage.tistory.com BlogIcon 환상경 2007.03.06 20:41 신고 address edit & del reply

    일헌....여기에 또 굇수님이 계셨쿤하~ >_<

    • lowid 2007.03.06 20:47 address edit & del

      머가 굇수에여...
      읽어보면 뭐가 먼지 다 아시면서...

  2. Favicon of http://firion.tistory.com BlogIcon 프리오닐 2007.03.07 00:18 신고 address edit & del reply

    몇일간 공중에 부양하고 계신 영혼 ㄲㄲㄲ 그러니까 괴수 맞지 ㄱ-

    • lowid 2007.03.07 16:09 address edit & del

      그건... 굇수가 아니라 퐤인이지....ㅋ

libconfuse 에서 *** glibc detected *** double free or corruption

CFG_SIMPLE_STR 이런식으로 했을시에
저런 에러가 난다면
먼저 문자열을 넣어 줬는지 체크한다
초기값은 NULL이 할당이 되어 있어야한다

그리고 libconfuse에서 값을 재대로 못읽어돌경우가 있는데
그 이유중하나가 큰따옴표를 빼먹어서 일 가능성도 있다
데이터가 없더라도 config파일에 큰쌍따옴표가 들어가게 해야한다
Trackback 0 Comment 0
prev 1 2 3 4 5 next