来源不可用和腐败堆 [英] Source not available and corrupt heap

查看:69
本文介绍了来源不可用和腐败堆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


我的问题是;


1)由于未知原因,VS说当触发异常时源不可用。尽管尝试通过options-> debug下载它们,但也未加载其他符号。同样重新安装和修复VS也无济于事。


至于我遇到的第二个问题:


这是我的程序,直到现在:

 #include< stdio.h> 
#include< stdlib.h>
#include< assert.h>

#pragma一次
#define MAX_VALUE 100
/ *断言:
大小必须大于或等于$
优先级必须大于或等于NULL
* /

typedef struct pqentry_t {
float priority;
char值;
struct priorityqueue_t * queue;
} pqentry_t;

typedef struct priorityqueue_t {
int head;
int tail;
int current;
int条目;
无符号长尺寸;
struct pqentry_t * entry;
} priorityqueue_t;

void check_func(char message [])
{
printf_s("%s",message);
}

结构priorityqueue_t * pqueue_create()
{
结构priorityqueue_t * PQ = malloc的(的sizeof(PQ->大小));
if(!pq)
{
check_func(" ALLOCATE MEMORY FOR QUEUE:\ nFAFA \ n");
返回;
}
check_func(" ALLOCATE MEMORY FOR QUEUE:\ nPASS \ n");
断言(pq-> size> = 0);
pq-> size = 0;
pq-> head = NULL;
pq-> tail = NULL;
pq-> current = NULL;
pq-> entries = NULL;
返回pq;
}

空隙pqueue_insert(priorityqueue_t * PQ,字符*值,浮动P)
{
结构pqentry_t * PE = malloc的(的sizeof(pqentry_t));
if(!pe)
{
check_func(" ALLOCATE MEMORY FOR ENTRY:\ nFAFA \ n");
返回;
}
check_func(" ALLOCATE MEMORY FOR ENTRY:\ nPASS \ n");
char uservalue [] =" TEST" ;; // TODO:MAX_VALUE& TEST
float userpriority = 0;

// TODO:实施scanf

断言(userpriority> = 0);
pe-> priority = userpriority;
pe-> value = uservalue;
pe-> queue = pq;
if(pq-> size == 0)
{
pq-> head = pe;
pq-> current = pe;
pq-> size ++;
返回;
}
for(int i = 0; i == pq-> size; ++ i)
{
if(pq-> entry-> priority> ; pe->优先级)
{
pq-> tail = pq-> current;
pq-> head = pe;
pq-> size ++;
}
}
realloc(pq,sizeof(pq));
}

void pqueue_destroy(priorityqueue_t * pq)
{
free(pq-> entries);
if(pq->条目)
{
check_func(" FREE ENTRYS:\ nFAFA \ n");
返回;
}
check_func(" FREE ENTRYS:\ nPASS \ n");
free(pq);
if(pq)
{
check_func(" FREE QUEUE:\ nFAFA \ n");
返回;
}
check_func(" FREE QUEUE:\ nPASS \ n");
}

int main()
{
struct priorityqueue_t * pq = pqueue_create();
短期决定;
printf_s(" Quit = 0 | insert = 1 | destroy = 2 \ n"); // TODO:检查正确的数字
scanf_s("%d",& decicsion);
while(decicsion!= - 1)
{
switch(decicsion)
{
case 0:
printf_s(" Breaking ... \\ \
");
decicsion = -1;
休息;
case 1:
pqueue_insert(pq," TEST",0.0);
scanf_s("%d",& decicsion);
休息;
案例2:
pqueue_destroy(pq);
休息;
案例3:
printf_s(" test");
scanf_s("%d",& decicsion);
休息;
}
}
// pqueue_insert(pqueue_create()," TEST",0.0);
返回0;
}




现在我总是在第52行得到以下异常:

在0x77A5A849(NTDLL.DLL)在OOA Praktikum 1.EXE

未处理的异常:0xC0000374:堆已被损坏(参数:0x77A95910)。发生了


我现在使用这种方法多次创建一个指针,即在其他程序中,从来没有得到过这个错误 也在函数create()中它起作用。


可以让sombody指向正确的方向吗?


提前致谢


编辑:出于某种原因我现在得到一个C ++运行时库异常窗口。


https://i.imgur.com/iAmafSs.png

解决方案

嗯,如果你设法使用它而不会造成错误,我会感到惊讶。


特别是有一条线突出:


<预类= "prettyprint">结构priorityqueue_t * PQ = malloc的(的sizeof(PQ->大小));

这应该很明显,因为priorityqueue_t :: size是一个unsigned long,其中priorityqueue_t是一个包含这个unsigned long的结构。如果你检测到这些的大小:

 int main()
{
struct priorityqueue_t * pq;
printf(" priorityqueue_t :: size%d \ n",sizeof(pq-> size));
printf(" priority of priorityqueue_t%d \ n",sizeof(struct priorityqueue_t));
返回0;
}

您将获得:


priorityqueue_t的大小:: size 4

size of priorityqueue_t 24


因此,您基本上为24字节大小的结构分配4个字节。现在我不知道在什么情况下你已经尝试了这个并且它成功了,但Windows对于malloc分配的对象大小非常挑剔,如果你分配4个字节,
然后写入结束然后Windows将一发现它就告诉你。所以你的问题是你没有为你的priorityqueue_t结构分配足够的内存。


无论如何,还有一些我想指出的问题。首先,我注意到您正在为pqentry_t中的char字段值分配一个char数组,这是为字符类型指定一个指针类型。指针类型总是比
大于字符类型,所以你破坏了那个值,指针也会被截断。


还有事实上,您在priorityqueue_t结构中使用int来存储指针。 int类型并不总是保证与指针的大小相同,因此这可能会导致指针损坏。


x64(AMD64,EMT64)就是这样一个平台int是4个字节,但指针是8个字节。因此,不是定义你的结构来获取一堆int,而是实际使用指针。


最后,如果你遇到这些问题,我建议你使用C ++编译你的代码。虽然你必须从malloc转换回报,但对于其余部分,C ++类型的安全性会指出C允许的东西,但是
你从来没有注意到它是一个问题。


Hi,

My issues are that;

1) For unknown reasons VS says source not available when an exception is triggered. Also other symbols are not loaded despite trying to download them via options->debug. Also reinstalling and repairing VS did not help.

As for the second issue I'm experiencing:

this is my program till now:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#pragma once
#define MAX_VALUE 100
/*  Asserts:
size must be greater or equal than NULL
priority must be greater or equal than NULL
*/

typedef struct pqentry_t {
	float priority;
	char value;
	struct priorityqueue_t *queue;
}pqentry_t;

typedef struct priorityqueue_t {
	int head;
	int tail;
	int current;
	int entries;
	unsigned long size;
	struct pqentry_t *entry;
}priorityqueue_t;

void check_func(char message[])
{
	printf_s("%s", message);
}

struct priorityqueue_t* pqueue_create()
{
	struct priorityqueue_t *pq = malloc(sizeof (pq->size));
	if (!pq)
	{
		check_func("ALLOCATE MEMORY FOR QUEUE:\nFAIL\n");
		return;
	}
	check_func("ALLOCATE MEMORY FOR QUEUE:\nPASS\n");
	assert(pq->size >= 0);
	pq->size = 0;
	pq->head = NULL;
	pq->tail = NULL;
	pq->current = NULL;
	pq->entries = NULL;
	return pq;
}

void pqueue_insert(priorityqueue_t *pq, char* value, float p)
{
	struct pqentry_t *pe = malloc(sizeof(pqentry_t));
	if (!pe)
	{
		check_func("ALLOCATE MEMORY FOR ENTRY:\nFAIL\n");
		return;
	}
	check_func("ALLOCATE MEMORY FOR ENTRY:\nPASS\n");
	char uservalue[] = "TEST";		//TODO: MAX_VALUE & TEST
	float userpriority = 0;

	//TODO: Implement scanf

	assert(userpriority >= 0);
	pe->priority = userpriority;
	pe->value = uservalue;
	pe->queue = pq;
	if (pq->size == 0)
	{
		pq->head = pe;
		pq->current = pe;
		pq->size++;
		return;
	}
	for (int i = 0; i == pq->size; ++i)
	{
		if (pq->entry->priority > pe->priority)
		{
			pq->tail = pq->current;
			pq->head = pe;
			pq->size++;
		}
	}
	realloc(pq, sizeof(pq));
}

void pqueue_destroy(priorityqueue_t *pq)
{
	free(pq->entries);
	if (pq->entries)
	{
		check_func("FREE ENTRYS:\nFAIL\n");
		return;
	}
	check_func("FREE ENTRYS:\nPASS\n");
	free(pq);
	if (pq)
	{
		check_func("FREE QUEUE:\nFAIL\n");
		return;
	}
	check_func("FREE QUEUE:\nPASS\n");
}

int main()
{
	struct priorityqueue_t *pq = pqueue_create();
	short decicsion;
	printf_s("Quit = 0 | insert = 1 | destroy = 2\n"); //TODO: CHECK FOR CORRECT NUMBERS
	scanf_s("%d", &decicsion);
	while (decicsion!=-1)
	{
		switch (decicsion)
		{
		case 0:
			printf_s("Breaking...\n");
			decicsion = -1;
			break;
		case 1:
			pqueue_insert(pq, "TEST", 0.0);
			scanf_s("%d", &decicsion);
			break;
		case 2:
			pqueue_destroy(pq);
			break;
		case 3:
			printf_s("test");
			scanf_s("%d", &decicsion);
			break;
		}
	}
	//pqueue_insert(pqueue_create(), "TEST", 0.0);
	return 0;
}


Now I always get the following exception at line 52:

Unhandled exception at 0x77A5A849 (ntdll.dll) in OOA Praktikum 1.exe: 0xC0000374: A heap has been corrupted (parameters: 0x77A95910). occurred

I used this method of creating a pointer now several times, i.e. in other programs and never got this error also in the function create() it works.

Can sombody point me in a right direction here?

Thanks in advance

EDIT: For some reason I now get a C++ runtime libary exception window.

https://i.imgur.com/iAmafSs.png

解决方案

Umm, well, I would be surprised if you managed to use this without errors being caused.

There is one line in particular that stands out:

struct priorityqueue_t *pq = malloc(sizeof(pq->size));

This should be quite obvious since priorityqueue_t::size is an unsigned long where priorityqueue_t is a structure that contains this unsigned long amongst other things. If you detect the sizes for these:

int main()
{
	struct priorityqueue_t *pq;
	printf("size of priorityqueue_t::size %d\n", sizeof(pq->size));
	printf("size of priorityqueue_t %d\n", sizeof(struct priorityqueue_t));
	return 0;
}

You will get:

size of priorityqueue_t::size 4
size of priorityqueue_t 24

So you are basically allocating 4 bytes for a structure that is 24 bytes in size. Now I don't know in what circumstances you have tried this and it succeeded, but Windows is quite picky with the sizes of objects allocated by malloc, if you allocate 4 bytes, and then write past the end then Windows will tell you as soon as it detects this. So your problem is that you are not allocating enough memory for your priorityqueue_t structure.

Anyway, there are another couple of issues that I would like to point out. First, I noticed that you are assigning an array of char to the char field value in pqentry_t, this is assigning a pointer type to a character type. Pointer types are always going to be larger than the character type, and so you are corrupting that value, the pointer is also going to be truncated too.

There is also the fact that you are using int in the priorityqueue_t structure to store pointers. The int type isn't always guaranteed to be the same size as a pointer, so this could lead to corruption of the pointer.

The x64 (AMD64, EMT64) is one such platform where int is 4 bytes, but pointers are 8 bytes. So instead of defining your structure to take a bunch of ints, actually use pointers.

Finally, if you are having these kinds of problems, I would suggest that you use C++ to compile your code. While you would have to cast the returns from malloc, for the rest of it the C++ type safety will point out things that C allows but you never would have noticed as being a problem.


这篇关于来源不可用和腐败堆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆