2014-12-12 8 views
1

현재 일부 XML 데이터를 이더넷을 통해 문자열로 보내는 코드를 작성 중입니다. 소켓에 보내려면 데이터가 먼저 만들어 져야합니다. 저는 STM32F4xx 타입 마이크로 컨트롤러를 사용하고 IAR EWARM 임베디드 개발 환경을 사용하고 있습니다. 그것은 2 번 정확하게 데이터를 전송C 언어를 사용하는 임베디드 시스템에서 안정적인 문자열 연결

Send:(09:41:17) alive 
Rec:(09:41:17)<data> 
<items> 
<radar x="1"></radar> 
<radar v="1"></radar> 
</items> 
</data> 
Send:(09:41:18) alive 
Rec:(09:41:18)<data> 
<items> 
<radar x="1"></radar> 
<radar v="1"></radar> 
</items> 
</data> 
Send:(09:41:18) alive 
Rec:(09:41:18)<data> 

만 6 자 기록 : 다음

char* concat(char *s1, char *s2) 
{ 
    size_t len1 = strlen(s1); 
    size_t len2 = strlen(s2); 
    char *result = malloc(len1+len2+1);//+1 for the zero-terminator 
    //in real code you would check for errors in malloc here 
    memcpy(result, s1, len1); 
    memcpy(result+len1, s2, len2+1);//+1 to copy the null-terminator 
    return result; 
} 

char* data = concat("<data>\n<items>\n<radar x=\"", "1"); 
data = concat(data, "\"></radar>\n<radar v=\""); 
data = concat(data, "1"); 
data = concat(data, "\"></radar>\n</items>\n</data>"); 
len = strlen(data); 

Socket_Send(data,len); 

이더넷 서버 출력 결과 :

나는 다음과 같은 기능을 사용하고있다. 이 문제를 어떻게 해결할 수 있습니까? 어떤 도움이라도 대단히 감사합니다. 미리 감사 ..

EDIT 1 추천 코드 :

data = concat("<data>\n<items>\n<radar x=\"", "1"); 
char *tmp = data; 
data = concat(data, "\"></radar>\n<radar v=\""); 
free(tmp); 
data = concat(data, "1"); 
data = concat(data, "\"></radar>\n</items>\n</data>"); 

len = strlen(data); 

출력 :

Send:(09:51:38) alive 
Rec:(09:51:38)<data> 
<items> 
<radar x="1"></radar> 
<radar v="1"></radar> 
</items> 
</data> 
Send:(09:51:40) alive 
Rec:(09:51:40)<data> 
<items> 
<radar x="1"></radar> 
<radar v="1"></radar> 
</items> 
</data> 
Send:(09:51:44) alive 
Rec:(09:51:44)<data> 
<items> 
<radar x="1"></radar> 
<radar v="1"></radar> 
</items> 
</data> 
Send:(09:51:44) alive 
Rec:(09:51:44)8 ¹Õ"></radar> 
</items> 
</data> 
Send:(09:51:44) alive 
Rec:(09:51:44)8 ¹Õ1"></radar> 
</items> 
</data> 
Send:(09:51:45) alive 
Rec:(09:51:45)8 ¹Õ1"></radar> 
</items> 
</data> 
Send:(09:51:45) alive 
Rec:(09:51:45)8 ¹Õ 
Send:(09:51:45) alive 
Rec:(09:51:45)8 ¹Õ 
Send:(09:51:46) alive 
Rec:(09:51:46)8 ¹Õ 
Send:(09:51:46) alive 
Rec:(09:51:46)8 ¹Õ 

EDIT 2 (불량한 SOLUTION)

char* data; 
char* data1; 
char* data2; 
char* data3; 
data1 = concat("<data>\n<items>\n<radar x=\"", "1"); 

data2 = concat(data1, "\"></radar>\n<radar v=\""); 
free(data1); 

data3 = concat(data2, "1"); 
free(data2); 

data = concat(data3, "\"></radar>\n</items>\n</data>"); 
free(data3); 

len = strlen(data); 
Socket_Send(data,len); 
free(data); 

EDIT 3 (SOLVED) :

XML에서 태그 수가 증가하면 mem 누수가 예상대로 발생했습니다. 사람들이 제안한대로, 나는 시도했다 strcat 그리고 그것은 효과가있다. 하지만 strcpy는 제 컴파일러에서 작동하지 않습니다. strcat을 사용하는 데 동일한 문제가있는 사람에게 강력히 제안합니다.

+2

: 당신에게 뭔가를 제공해야

len = strlen(data); dump(data, len + 1, 8); /* +1 to include trailing zero */ free(data); 

. 슬프게도 경험에 의하면 동적으로 할당 된 메모리에 대한 포인터를 반환하는 함수가 어딘가에있는 프로그램은 거의 확실하게 메모리 누수가 있음을 알 수 있습니다. – Lundin

+1

사이드 노트 :'memcpy, memcpy' 대신'strcpy, strcat'을 사용하십시오. –

+0

사이드 노트 # 2 : 모든 런타임 연결을 시작할 필요가없는 것 같습니다. 모든 문자열은 상수이므로 한 문자열 만 정적으로 할당 할 수 있습니다. 추가적인 안전성 (동적 메모리 할당/할당 취소를 피함), 런타임 성능을 향상 시키며, 프로그램 실행 중 문자열이 동일한 메모리 주소에 상주하기 때문에 일정하게 유지합니다 예상치 못한 캐싱 영향 없음 등). 일정한 실행 시간은 일반적으로 임베디드 시스템에서 중요한 측면으로 간주됩니다. –

답변

1

당신은 아래의 통화에서 메모리 누수를 많이하고 있습니다 :

data = concat(data, "\"></radar>\n<radar v=\""); 

올바른 누출이 예상대로 작동합니다 프로그램.

한 가지 가능한 수정 :

{ 
    char *tmp = data; 
    data = concat(data, "\"></radar>\n<radar v=\""); 
    free(tmp); 
} 

또한 malloc 후, 할당의 성공 여부를 확인한다.

+0

지금 시도하십시오 – mozcelikors

+0

내 편집 확인하십시오 – mozcelikors

+0

또한 수신 측면에 누출이 없는지 확인하십시오. 내가 valgrind 도구를 사용하는 것이 좋습니다 것입니다. –

1

컨텍스트에 따라 필요에 따라 concat 함수를 약간 다시 작성할 수도 있습니다. 첫 번째 인수로 다시 할당 할 수있는 버퍼를 만듭니다. 그런 다음 내부에서 자유롭게 할당하고 새로운 ptr을 반환하십시오.

char *concat(char *s1, char *s2) 
{ 
    size_t len1 = s1 ? strlen(s1) : 0; 
    size_t len2 = strlen(s2) + 1; 
    char *result; 

    result = malloc(len1 + len2); 
    memcpy(result, s1, len1); 
    memcpy(result + len1, s2, len2); 
    free(s1); 

    return result; 
} 

그리고

는 다른 코드에서 말 :

size_t len; 
char *data = NULL; 

data = concat(data, "<data>\n<items>\n<radar x=\""); 
data = concat(data, "1"); 
data = concat(data, "\"></radar>\n<radar v=\""); 
data = concat(data, "1"); 
data = concat(data, "\"></radar>\n</items>\n</data>"); 


Socket_Send(data, strlen(data)); 
free(data); 

측면 지점으로 가끔 콘솔에 데이터를 덤프하는 것이 도움이 될 수 있습니다 -이 올바른지 확인합니다.그럼 당신은 말할 수

#include <ctype.h> 

void dump_txt(const char *buf, int len) 
{ 
    int i; 

    fprintf(stdout, " "); 
    for (i = 0; i < len; ++i) 
     fprintf(stdout, "%c", isprint(buf[i]) ? buf[i] : '.'); 
    fprintf(stdout, "\n"); 
} 

void dump(const char *buf, int len, int width) 
{ 
    int i, k; 

    for (i = 0; i < len; ++i) { 
     if (i && !(i % width)) 
      dump_txt(buf + (i - width), width); 
     fprintf(stdout, "%02x ", buf[i]); 
    } 
    k = i; 
    for (k = i ; k % width; ++k) 
     fprintf(stdout, " "); 
    dump_txt(buf + (i - (i % width)), k - i); 
} 

: 그런 짓을 난 강력 알고리즘에서 별도의 메모리 할당을 유지하기 위해 제안

3c 64 61 74 61 3e 0a 3c <data>.< 
69 74 65 6d 73 3e 0a 3c items>.< 
72 61 64 61 72 20 78 3d radar x= 
22 31 22 3e 3c 2f 72 61 "1"></ra 
64 61 72 3e 0a 3c 72 61 dar>.<ra 
64 61 72 20 76 3d 22 31 dar v="1 
22 3e 3c 2f 72 61 64 61 "></rada 
72 3e 0a 3c 2f 69 74 65 r>.</ite 
6d 73 3e 0a 3c 2f 64 61 ms>.</da 
74 61 3e 00    ta>. 
+0

내 편집을 확인하십시오. 그것은 현재 작동합니다. 덤핑 데이터 설명 +1 – mozcelikors