我有一个使用此代码的程序的长版本和一个短版本。这是短版本,奇怪的是,这段代码在短版本程序中运行得非常好,但是因为在大版本中遇到了访问冲突,我感觉出了问题。是否有人发现以下代码有任何严重错误(可能导致数据损坏和/或访问冲突错误)?或者这样可以吗?
char strlist[5][11] = {
{ "file01.txt" },
{ "file02.txt" },
{ "file03.txt" },
{ "file04.txt" },
{ "file05.txt" }
};
typedef struct DYNAMEM_DATA {
char *string;
int strlen;
} DYNAMEM_DATA;
typedef struct DYNAMEM_STRUCT {
struct DYNAMEM_DATA **data;
int num_elements;
} DYNAMEM_STRUCT;
DYNAMEM_STRUCT *create_dynamem_struct(int num_elements, char *strlist)
{
DYNAMEM_STRUCT *ds = (DYNAMEM_STRUCT *)calloc(1, sizeof(DYNAMEM_STRUCT));
wchar_t wstring[128];
char len[3];
int i;
ds->data = (DYNAMEM_DATA **)calloc(num_elements, sizeof(DYNAMEM_DATA *));
ds->num_elements = num_elements;
for(i = 0; i < num_elements; i++) {
ds->data[i] = (DYNAMEM_DATA *)calloc(1, sizeof(DYNAMEM_DATA));
ds->data[i]->string = (char *)calloc(1, strlen(&strlist[i*11])+5);
ds->data[i]->strlen = strlen(&strlist[i*11]);
sprintf(ds->data[i]->string, "%s, %d", &strlist[i*11], ds->data[i]->strlen);
mbstowcs(wstring, ds->data[i]->string, 128);
MessageBox(NULL, wstring, TEXT("Error"), MB_OK);
}
return ds;
}
最佳答案
此代码运行,生成5条“错误”消息(这是预期的),并且不会泄漏任何内存。在Mac OS X 10.7.4(使用GCC 4.7.1)上运行valgrind
(3.7.0),它会得到一个干净的健康清单。
显然,问题不在这个版本的代码中。
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <wchar.h>
char strlist[5][11] = {
{ "file01.txt" },
{ "file02.txt" },
{ "file03.txt" },
{ "file04.txt" },
{ "file05.txt" }
};
typedef struct DYNAMEM_DATA {
char *string;
int strlen;
} DYNAMEM_DATA;
typedef struct DYNAMEM_STRUCT {
struct DYNAMEM_DATA **data;
int num_elements;
} DYNAMEM_STRUCT;
enum { MB_OK = 0 };
static void destroy_dynamem_data(DYNAMEM_DATA *dd)
{
free(dd->string);
free(dd);
}
static void destroy_dynamem_struct(DYNAMEM_STRUCT *ds)
{
for (int i = 0; i < ds->num_elements; i++)
destroy_dynamem_data(ds->data[i]);
free(ds->data);
free(ds);
}
static void MessageBox(const void *null, const wchar_t *wcs, const char *ncs, int status)
{
if (null == 0 || status == MB_OK)
fprintf(stderr, "%s\n", ncs);
else
fwprintf(stderr, L"%s\n", wcs);
}
static const char *TEXT(const char *arg) { return arg; }
extern DYNAMEM_STRUCT *create_dynamem_struct(int num_elements, char *strlist);
DYNAMEM_STRUCT *create_dynamem_struct(int num_elements, char *strlist)
{
DYNAMEM_STRUCT *ds = (DYNAMEM_STRUCT *)calloc(1, sizeof(DYNAMEM_STRUCT));
wchar_t wstring[128];
//char len[3];
int i;
ds->data = (DYNAMEM_DATA **)calloc(num_elements, sizeof(DYNAMEM_DATA *));
ds->num_elements = num_elements;
for(i = 0; i < num_elements; i++) {
ds->data[i] = (DYNAMEM_DATA *)calloc(1, sizeof(DYNAMEM_DATA));
ds->data[i]->string = (char *)calloc(1, strlen(&strlist[i*11])+5);
ds->data[i]->strlen = strlen(&strlist[i*11]);
sprintf(ds->data[i]->string, "%s, %d", &strlist[i*11], ds->data[i]->strlen);
mbstowcs(wstring, ds->data[i]->string, 128);
MessageBox(NULL, wstring, TEXT("Error"), MB_OK);
}
return ds;
}
int main(void)
{
DYNAMEM_STRUCT *ds = create_dynamem_struct(5, strlist[0]);
destroy_dynamem_struct(ds);
return 0;
}
关于c - 臭名昭著的动态分配结构数组的指针,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12326558/