我有一个squeue(堆栈和队列的组合)。我有一个名为mergeFront的函数,该作业应该将前两个节点合并为一个。例如,如果前节点是" alpha"第二个节点是" beta"它们应该合并到" alphabeta"。
alias python="python3"
当我在最后一行中void mergeFront(struct Squeue* squeue){
struct Node* temp;
char *string;
char *tempstring=malloc(sizeof(char)*100);
temp = squeue->first;
temp = temp->next;
string = squeue->first->val;
strcpy(tempstring, string);
string = temp->val;
strcat(tempstring, string);
squeue->first->next->val=tempstring;
temp = squeue->first;
squeue->first = temp->next;
free(temp);
free(tempstring);
}
时,第一个节点现在变为空(假设因为我有空闲' d指向的值)。如果我摆脱free(tempstring)
它运行良好但存在内存泄漏。如何在正确释放内存的同时执行此操作?
节点结构如下
free(tempstring)
在获取@ikegami给出的代码后,我的代码如下:
struct Node{
char* val;
struct Node* next;
struct Node* prev;
};
}
它完全正常运行,但我仍然在1块中获得10字节的泄漏内存。关于我在哪里找到这个的任何线索?
答案 0 :(得分:0)
你想做什么:
-
void mergeFront(struct Squeue* squeue){
// Make sure there are at least 2 nodes
if (NULL == squeue->first || NULL == squeue->first->next) {
return;
}
// 1. Allocate space for the new string
char *tempstring = malloc(strlen(squeue->first->val) +
strlen(squeue->first->next->val) + 1);
if (NULL == tempstring) {
// Out of memory
return;
}
// 2. Merge the 2 old strings into the new string
sprintf(tempstring, "%s%s", squeue->first->val, squeue->first->next->val);
// 3. Delete the 2 old strings
free(squeue->first->val);
free(squeue->first->next->val);
// 4. Delete the first node, and update first node
struct Node* temp = squeue->first;
squeue->first = squeue->first->next;
squeue->first->prev = NULL;
free(temp);
// 5. Assign the new string to the new first node
squeue->first->val = tempstring;
}
答案 1 :(得分:0)
void mergeFront(struct Squeue* squeue) {
/* Make sure we have at least two nodes. */
struct Node* node1 = squeue->first; if (node1 == NULL) return;
struct Node* node2 = node1->next; if (node2 == NULL) return;
/* Create the combined string. */
char* str1 = node1->val; size_t str1len = strlen(str1);
char* str2 = node2->val; size_t str2len = strlen(str2);
char* merged = malloc(str1len + str2len + 1);
memcpy(merged, str1, str1len);
strcpy(merged+str1len, str2);
/* Replace the first node's string with the combined string. */
free(node1->val);
node1->val = merged;
deleteNode(squeue, node2);
}
助手:
void deleteNode(struct Squeue* squeue, struct Node* node) {
if (node->prev == NULL)
squeue->first = node->next;
else
node->prev->next = node->next;
if (node->next == NULL)
squeue->last = node->prev;
else
node->next->prev = node->prev;
free(node->val);
free(node);
}
注意:
tempstring
(现在称为merged
)指向的内存,因为它仍在使用(squeue->first->val
)!* sizeof(char)
没用,因为sizeof(char)
总是1
。由于你将这称为#stack; queue-queue",使用堆栈和队列操作会更有意义。
void mergeFront(struct Squeue* squeue) {
struct Node* node1 = shift(squeue);
if (node1 == NULL) {
return;
}
struct Node* node2 = shift(squeue);
if (node2 == NULL) {
unshift(squeue, node1);
return;
}
char* str1 = node1->val; size_t str1len = strlen(str1);
char* str2 = node2->val; size_t str2len = strlen(str2);
node1->val = realloc(node1->val, str1len + str2len + 1);
strcpy(node1->val + str1len, node2->val);
freeNode(node2);
unshift(squeue, node1);
}
助手:
void freeNode(struct Node* node) {
free(node->val);
free(node);
}
struct Node* shift(struct Squeue* squeue) {
struct Node* node = squeue->first;
if (node == NULL)
return NULL;
squeue->first = node->next;
if (node->next == NULL)
squeue->last = NULL;
else {
node->next->prev = NULL;
node->next = NULL;
}
return node;
}
struct Node* pop(struct Squeue* squeue) {
struct Node* node = squeue->last;
if (node == NULL)
return NULL;
squeue->last = node->prev;
if (node->prev == NULL)
squeue->first = NULL;
else {
node->prev->next = NULL;
node->prev = NULL;
}
return node;
}
void unshift(struct Squeue* squeue, struct Node* node) {
if (squeue->first == NULL) {
squeue->first = node;
squeue->last = node;
} else {
node->next = squeue->first;
squeue->first = node;
}
}
void push(struct Squeue* squeue, struct Node* node) {
if (squeue->last == NULL) {
squeue->first = node;
squeue->last = node;
} else {
node->prev = squeue->last;
squeue->last = node;
}
}
测试。
答案 2 :(得分:0)
这看起来很奇怪
squeue->first->next->val=tempstring;
temp = squeue->first;
squeue->first = temp->next;
free(temp);
free(tempstring);
首先你分配tempstring并指定一个指针val指向它,但后来你释放它使val指向无效。
似乎你应该跳过free(tempstring)
为了合并两个节点。首先检查两个字符串的长度,以分配足够的空间而不是假设100就足够了。分配一个缓冲区,可以包含两个字符串加上结尾\ 0,即在两个字符串上使用strlen()并添加一个。
此后strcpy / strcat两个值都到该缓冲区。
然后释放第一个和第二个节点指向的字符串
然后将第一个节点指定为指向此新节点
然后在第一个节点中设置指针以消除第二个节点,不要忘记释放第二个节点。即每个节点是两个分配,一个用于节点本身,另一个用于它所拥有的字符串。