내부 mmost에있는 데이터를 전달하거나 액세스하기 위해 struct
최상위 레이어에 struct
대한 포인터를 사용하는 인수 목록이있는 여러 계층의 중첩 및 함수 프로토 타입 을 생성하는 코드 생성기에서 생성 된 ANSI C 코드 를 사용하고 있습니다 struct
.
함수 프로토 타입은 포인터를 구조체에 전달하기 때문에 응용 프로그램은 대부분의 내부 구조체 멤버에 액세스하거나 데이터를 쓰기 위해 메모리를 할당해야합니다. 두 번째 중첩 구조체에 대한 포인터에 메모리를 할당하려고 할 때 문제가 발생합니다.
내가 얻는 실제 오류 메시지는 치명적이지 않은 런타임입니다. " '구조물에 대한 포인터'로 식을 캐스팅 할 공간이 충분하지 않습니다."
나는 명시 적으로 아무것도 캐스팅하지 않고 있으므로 구현에 malloc()
어떤 조건이있을 때 메시지를 생성하는 어설 션이있을 수 있다고 생각합니다. 이 오류의 문구는 내 환경에 따라 다를 수 있지만 (LabWindows / CVI를 사용하고 있습니다) 다른 ANSI C 컴파일러의 결과도 듣고 싶습니다.
다음은 컴파일, 빌드 및 실행해야하는 단순하고 완전한 코드 스 니펫입니다 (인라인으로 주석 처리 된 오류 위치까지).
내 오류의 원인에 대한 의견과 수정 방법에 대한 제안에 감사드립니다.
#include <ansi_c.h> //specific to LabWindows/CVI - change as needed for your environment
struct request
{
struct data *pData;
};
struct data
{
char *wsDate;
char *wsDuration;
char *wsFailures;
int __sizeM_Details;
struct details *M_Details;
};
struct details
{
char *wsStep;
char *wsTestDesc;
char *wsLowLim;
};
typedef struct request REQUEST; // from mtdf function prototype request argument (4)
typedef struct details DETAILS; // member of REQUEST - _ns1__MTDFData_MTDFDetail
void allocate(REQUEST *a, int numRecords);
void freemem(REQUEST *c, int numRecords);
int main(void)
{
REQUEST b, *pB;
pB = &b;
allocate(pB, 10);
freemem(pB, 10);
return 0;
}
void allocate(REQUEST *c, int numRecords)
{
DETAILS m_Param;
REQUEST b;
struct data d;
size_t size_c = sizeof(c);
c = malloc(size_c); //4 bytes
size_t size_c_data = sizeof(c->pData);
c->pData = malloc(size_c_data); //Breaks here - this is just a pointer,
//should it not just allocate 4 bytes
//and continue?
// Actual error message:
// "Not enough space for casting expression to 'pointer to struct data'."
c->pData->wsDate = calloc(80, sizeof(char));
c->pData->__sizeM_Details = numRecords;
c->pData->M_Details = calloc((numRecords + 1) , sizeof(m_Param));
}
void freemem(REQUEST *c, int numRecords)
{
free(c->pData->M_Details);
free(c->pData->wsDate);
free(c->pData);
free(c);
}
여기에 몇 가지 근본적인 문제가 있습니다.
에서는 함수 가 끝날 때 파괴되는 지역 변수에 할당하기 때문에 함수가 끝날 allocate()
때 모든 메모리 malloc()
가 손실됩니다 c
. 함수에 전달하는 자동 저장 기간과 함께 구조체의 주소를 사용하지 않습니다. 자동 저장 기간이있는 객체의 주소를 전달하는 경우 malloc()
에는 분명히 이미 메모리가 있으므로 구조체 자체가 아닌 멤버를 메모리 해야 합니다.
그런 다음에서 자동 저장 기간이있는 구조체 인에 연결된 메모리 freemem()
를 시도합니다 . 동적으로 할당 한 메모리 만 사용할 수 있습니다 .free()
b
free()
에서 allocate()
"이것은 단지 포인터 일 뿐이며 4 바이트를 할당하고 계속해야하지 않습니까?" 라는 흥미로운 주석 이 있습니다. 32 비트 포인터가있는 시스템에있는 경우 실제로 할당 한 것이지만 32 비트 시스템에서 28 바이트가 필요한 것처럼 보이는 c->pData
포인터 struct data
이므로 4 바이트 이상을 할당해야합니다. 그것. 같은 줄은 c->pData->wsDate = ...
그것이에 대한 포인터라는 것을 잘 알고 있음을 나타내는 것처럼 보이 struct data
므로 4 바이트 만 할당해야한다고 생각하는 이유가 명확하지 않습니다. 에 대한 메모리를 할당 할 때에 대한 메모리 ANYTHING *
를 할당해야합니다.에 대한 메모리가 ANYTHING
아니라에 대한 메모리를 할당해야 합니다 ANYTHING *
. 즉 , 가리키는 대상에 대한 충분한 메모리를 할당해야 합니다.. 처음에 포인터에 메모리를 할당하려고한다는 사실은 이미 포인터에 대한 메모리를 가지고 있음을 증명합니다. 그렇지 않으면 그렇게 할 수 없습니다 (이전의 일부를 엉망으로 만들지 않았다는 것을 제공). 물론 할당).
malloc()
및 의 수익을 확인하지 마십시오 calloc()
.
이중 밑줄로 시작하는 이름은 항상 구현을 위해 예약되어 있으므로 __sizeM_Details
다른 이름을 호출해야 합니다.
sizeof(char)
정의에 따라 1이므로 사용할 필요가 없습니다.
당신이 메모리를 할당하는 이유는 불분명 numRecords + 1
당신의 struct details
단지보다는 numRecords
직관적 보인다. 아마도 마지막 NULL
값을 센티넬 값으로 설정하려고 할 수도 있지만 이미 구조체에 레코드 수를 저장하고 있다면 실제로 필요하지 않습니다.
코드는 다음과 같아야합니다.
#include <stdio.h>
#include <stdlib.h>
struct request {
struct data * pData;
};
struct data {
char * wsDate;
char * wsDuration;
char * wsFailures;
int sizeM_Details;
struct details * M_Details;
};
struct details {
char * wsStep;
char * wsTestDesc;
char * wsLowLim;
};
typedef struct request REQUEST;
typedef struct details DETAILS;
void allocate(REQUEST * c, const int numRecords);
void freemem(REQUEST * c);
int main(void)
{
REQUEST b;
allocate(&b, 10);
freemem(&b);
return 0;
}
void allocate(REQUEST * c, const int numRecords)
{
if ( !(c->pData = malloc(sizeof *c->pData)) ) {
perror("couldn't allocate memory for c->pData");
exit(EXIT_FAILURE);
}
if ( !(c->pData->wsDate = calloc(80, 1)) ) {
perror("couldn't allocate memory for c->pData->wsDate");
exit(EXIT_FAILURE);
}
if ( !(c->pData->M_Details = calloc(numRecords + 1,
sizeof(*c->pData->M_Details))) ) {
perror("couldn't allocate memory for c->pData->M_Details");
exit(EXIT_FAILURE);
}
c->pData->sizeM_Details = numRecords;
}
void freemem(REQUEST * c)
{
free(c->pData->M_Details);
free(c->pData->wsDate);
free(c->pData);
}
에 대한 자동 스토리지 할당 b
이 실수이고을 포함하여 모든 것을 동적으로 할당하려는 struct request
경우 다음과 같이 표시됩니다.
#include <stdio.h>
#include <stdlib.h>
struct request {
struct data * pData;
};
struct data {
char * wsDate;
char * wsDuration;
char * wsFailures;
int sizeM_Details;
struct details * M_Details;
};
struct details {
char * wsStep;
char * wsTestDesc;
char * wsLowLim;
};
typedef struct request REQUEST;
typedef struct details DETAILS;
REQUEST * allocate(const int numRecords);
void freemem(REQUEST * c);
int main(void)
{
REQUEST * b = allocate(10);
freemem(b);
return 0;
}
REQUEST * allocate(const int numRecords)
{
REQUEST * c = malloc(sizeof *c);
if ( !c ) {
perror("couldn't allocate memory for c");
exit(EXIT_FAILURE);
}
if ( !(c->pData = malloc(sizeof *c->pData)) ) {
perror("couldn't allocate memory for c->pData");
exit(EXIT_FAILURE);
}
if ( !(c->pData->wsDate = calloc(80, 1)) ) {
perror("couldn't allocate memory for c->pData->wsDate");
exit(EXIT_FAILURE);
}
if ( !(c->pData->M_Details = calloc(numRecords + 1,
sizeof(*c->pData->M_Details))) ) {
perror("couldn't allocate memory for c->pData->M_Details");
exit(EXIT_FAILURE);
}
c->pData->sizeM_Details = numRecords;
return c;
}
void freemem(REQUEST * c)
{
free(c->pData->M_Details);
free(c->pData->wsDate);
free(c->pData);
free(c);
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다