c - C :: 内存访问冲突随机出现在链表中
问题描述
所以这是让我头疼的代码:
void newCopy(ListNode* n, List* l) {
if (n == NULL) { return; }
if (n->next == NULL) {
push(n->data, l);
return;
}
else {
newCopy(n->next, l);
push(n->data, l);
return;
}
}
如您所见,如果 n == NULL 则该函数应该结束,但您看到它即将到来:它并没有结束该函数。
if (n->next == NULL)
由于 n 为 NULL ,我得到“读取访问冲突” 。我在其他功能上也随机出现错误,所有这些都与内存访问有关。您应该研究的功能是State* progDynState(List* taskList)
因为一切都在这里完成。
我知道有些人想要最小的可复制示例,我无法制作一个,因为所有内容都已使用,所以这里是整个代码。
文件主要:
#include "Tools.h"
#include <time.h>
int main()
{
/* initialize random seed: */
srand(time(NULL));
//List creation
//
List* taskList = consList();
Task* task = NULL;
//Task number
/*int n = (rand() % 14 + 4);
//Generate random tasks
for(int i = 1; i <= n; i++) {
task = consTask(i + (rand() % 10 + 1) - rand() % 5 , i + (rand() % 10 + 1) - rand() % 5);
push(task, taskList);
}*/
for (int i = 1; i <= 4; i++) {
task = consTask(i,i);
push(task, taskList);
}
std::cout << "Display origin : \n" << listToString_Task(taskList) << " \n";
//--- CLASSIC ---
//SOLVE PROBLEM - PROG DYN STATE
State* opt = progDynState(taskList);
//--- FPTAS ---
double sigma = 1; //TO CHANGE DEPENDING ON PRECISION
//Get deltas
double deltaD = findDeltaD(taskList, sigma);
double deltaL = findDeltaL(taskList, sigma);
//Rounded values
List* rL = rounding(taskList, deltaD, deltaL);
//SOLVE PROBLEM - PROG DYN STATE
std::cout << "ROUNDED OPT : \n";
State* roundedOpt = progDynState(rL);
//Transpose the solution on the original instance
List* pair = createListTaskPair(taskList, rL);
State* FPTASopt = transpose(roundedOpt, pair);
std::cout << "Optimal Solution 2 : \n" << stateToString(FPTASopt) << " \n";
}
文件问题元素.h
#pragma once
#include <string>
#include <iostream>
#include <sstream>
#include <cmath>
#include <algorithm>
#ifndef PROBLEM
#define PROBLEM
// -----------------------------------------------------//
// ------------------ LIST ------------------//
// -----------------------------------------------------//
typedef struct ListNode ListNode;
struct ListNode
{
void *data;
struct ListNode *next;
};
typedef struct List List;
struct List
{
struct ListNode *head;
struct ListNode *tail;
int size;
};
//Initialize a list's value
void empty(List* l);
//Create an empty list
List* consList() //allocate and initialize to NULL values
{
List* list = (List*)calloc(1,sizeof(List*));
while(list == NULL) list = (List*)calloc(1,sizeof(List*));
empty(list);
return list;
}
//Add data to the head of the list
void push(void *data, List *list)
{
if (list == NULL) return;
if (data == NULL) return;
ListNode *newNode = (ListNode*)calloc(1,sizeof(ListNode));
newNode->data = data;
newNode->next = list->head;
if (list->head == NULL) //the list is empty
{
list->head = newNode;
list->tail = list->head;
}
else
{
list->head = newNode;
}
list->size++;
}
//Add data to the tail of the list
void append(void *data, List *list)
{
if (list == NULL) return;
if (data == NULL) return;
ListNode *newNode = (ListNode*)calloc(1,sizeof(ListNode));
newNode->data = data;
newNode->next = NULL;
if (list->head == NULL) //the list is empty
{
list->head = newNode;
list->tail = list->head;
}
else
{
list->tail->next = newNode;
list->tail = newNode;
}
list->size++;
}
//Remove first element
void pop(List* l) {
if (l == NULL) return;
if (l->head->next == NULL) {
free(l->head);
empty(l);
}
else {
ListNode* ln = l->head;
l->head = ln->next;
free(ln);
}
l->size--;
}
void endPop(List* l) {
if (l == NULL) return;
if (l->head->next == NULL) {
pop(l);
}
else {
ListNode* curr = l->head;
ListNode* prev = NULL;
while (curr != l->tail) {
prev = curr;
curr = curr->next;
}
free(l->tail);
prev->next = NULL;
l->size--;
}
}
//Remove element contening data
void removeData(void *data, List *list){
if (data == NULL) return;
if (list == NULL) return;
if (list->head == NULL) return;
//Head to be removed
if (data == list->head->data) {
pop(list);
return;
}
//Tail to be removed
if (data == list->tail->data){
endPop(list);
return;
}
//Other node
ListNode* curr = list->head;
ListNode* prev = NULL;
while (curr->data != data) {
prev = curr;
curr = curr->next;
}
prev->next = curr->next;
free(curr);
list->size--;
}
//Make l1's head and tail point to l2's
void assignTo(List* l1, List* l2) {
if (l1 == NULL) return;
if (l2 == NULL) return;
l1->head = l2->head;
l1->tail = l2->tail;
l1->size = l2->size;
}
//Initialize a list's value
void empty(List* l) {
if (l == NULL) return;
l->head = NULL;
l->tail = NULL;
l->size = 0;
}
//Free memory of all nodes
void freeNodes(List* l) {
if (l == NULL) return;
if (l->head->next == NULL) {
pop(l);
return;
}
while (l->head != NULL) {
pop(l);
}
}
//Create a copy of n in l with new elements, shared data pointer
void newCopy(ListNode* n, List* l) {
if (n == NULL) { return; }
if (n->next == NULL) {
push(n->data, l);
return;
}
else {
newCopy(n->next, l);
push(n->data, l);
return;
}
}
// -----------------------------------------------------//
// ------------------ STATE ------------------//
// -----------------------------------------------------//
typedef struct State State;
struct State
{
double _eOe; //End of execution
double _t; //Start of next task on first machine
//First machine
List* _task1;
//Second machine
List* _task2;
};
//Constructor of State
State* consState(double eOe = 0, double t = 0) {
State* s = (State*)malloc(sizeof(State));
s->_t = t;
s->_eOe = eOe;
s->_task1 = consList();
s->_task2 = consList();
return s;
}
//Describe a list of task
std::string listToString_Task(List* tL);
//Describe a state
std::string stateToString(struct State * s) {
std::string st;
st += "State : ( t = " + std::to_string(s->_t) + " , eOe = " + std::to_string(s->_eOe) + " ) \n";
st += "Task on machine 1 : (" + listToString_Task(s->_task1) + ") \n";
st += "Task on machine 2 : (" + listToString_Task(s->_task2) + ") \n";
st += "End of execution : " + std::to_string(s->_eOe);
return st;
}
// -----------------------------------------------------//
// ------------------ TASK ------------------//
// -----------------------------------------------------//
typedef struct Task Task;
struct Task
{
double _dur;//task duration
double _lat;//task latency
};
//Constructor of Task
Task* consTask(double dur = 0, double lat = 0) {
Task* t = (Task*)malloc(sizeof(Task));
t->_dur = dur;
t->_lat = lat;
return t;
}
//Describe a task
std::string taskToString(struct Task * t) {
return "Task : ( _dur = " + std::to_string(t->_dur) + " , _lat = " + std::to_string(t->_lat) + " )";
}
// -----------------------------------------------------//
// ------------------ PAIR : TASK | ROUNDED TASK ------------------//
// -----------------------------------------------------//
typedef struct TaskPair TaskPair;
struct TaskPair
{
Task* _origin;//original Tasks
Task* _rounded;//rounded Tasks
};
//Constructor of TaskPair
TaskPair* consTaskPair(Task* origin, Task* rounded) {
TaskPair* t = (TaskPair*)malloc(sizeof(TaskPair));
t->_origin = origin;
t->_rounded = rounded;
return t;
}
//Describe a task
std::string taskPairToString(struct TaskPair * t) {
return "TaskPair : ( origin = " + taskToString(t->_origin) + " , rounded = " + taskToString(t->_rounded) + " )";
}
#endif // !PROBLEM
文件工具.h
#pragma once
#include "ProblemElements.h"
#ifndef TOOLS
#define TOOLS
// -----------------------------------------------------//
// ------------------ GENERAL TOOLS ------------------//
// -----------------------------------------------------//
std::string listToString_State(List* sL);
//Keeps only the best state of a PElement<State>.
List* keepBestState(List* sL) {
if (sL == NULL) return NULL;
if (sL->head->next == NULL) return sL;
std::cout << "Size : " << std::to_string(sL->size) << "\n";
std::cout << "sL : " << listToString_State(sL) << "\n";
State* currS = (State*)sL->head->data;
State* nextS = (State*)sL->head->next->data;
//Current element is better, removing following element | Following element is better, removing current element
if(currS->_eOe <= nextS->_eOe)
removeData(sL->head->next->data, sL);
else
pop(sL);
return keepBestState(sL);
}
//Split List in two half
void splitList(List* sL, List* half2) {
//Size of list to sort
int listSize = sL->size;
//Half of size list
if (listSize % 2 == 0) {
listSize = listSize / 2;
sL->size = listSize;
half2->size = listSize;
}
else {
listSize = (listSize + 1) / 2;
sL->size = listSize;
half2->size = listSize-1;
}
ListNode* front = sL->head;
for (int i = 1; i < listSize; i++)
front = front->next;
//Start 2 half
half2->head = front->next;
//Cut main list
front->next = NULL;
//Set tails
half2->tail = sL->tail;
sL->tail = front;
}
//Merge two list of States sorted in increasing order into one list which is in increasing order || Comparing _t value
ListNode* sortedMerge_State(ListNode* a, ListNode* b)
{
ListNode* result = NULL;
//BASE CASE
if (a == NULL)
return(b);
if (b == NULL)
return(a);
State* state1 = (State*)a->data;
State* state2 = (State*)b->data;
//Sort current value
if (state1->_t <= state2->_t)
{
result = a;
result->next = sortedMerge_State(a->next, b);
}
else
{
result = b;
result->next = sortedMerge_State(a, b->next);
}
return result;
}//Merge two list of States sorted in increasing order into one list which is in increasing order
//Merge two list of Tasks sorted in decreasing order into one list which is in decreasing order || Comparing _lat value
ListNode* sortedMerge_Task(ListNode* a, ListNode* b)
{
ListNode* result = NULL;
if (a == NULL)
return(b);
if (b == NULL)
return(a);
Task* task1 = (Task*)a->data;
Task* task2 = (Task*)b->data;
if (task1->_lat >= task2->_lat)
{
result = a;
result->next = sortedMerge_Task(a->next, b);
}
else
{
result = b;
result->next = sortedMerge_Task(a, b->next);
}
return result;
}
//Sort a list of States by increasing order || Comparing _t value
void fusionSort_State(List* sL) {
ListNode* head = sL->head;
List* half2 = consList();
if (head == NULL || head->next == NULL) return;
//Cut list in two half
splitList(sL, half2);
//Recursiv call || Sort the two half
fusionSort_State(sL);
fusionSort_State(half2);
//Merge and sort the sorted halfs
sL->head = sortedMerge_State(sL->head,half2->head);
sL->size = sL->size + half2->size;
for (head = sL->head; head->next != NULL; head = head->next);
sL->tail = head;
}
//Sort a list of Tasks by decreasing order || Comparing _lat value
void fusionSort_Task(List* sL) {
ListNode* head = sL->head;
List* half2 = consList();
if (head == NULL || head->next == NULL) return;
splitList(sL, half2);
fusionSort_Task(sL);
fusionSort_Task(half2);
sL->head = sortedMerge_Task(sL->head,half2->head);
sL->size = sL->size + half2->size;
for (head = sL->head; head->next != NULL; head = head->next);
sL->tail = head;
}
//Removes multiple occurence t
List* removeMultOcc(List* sL) {
if (sL == NULL) return NULL;
if (sL->head == NULL) return NULL;
if (sL->size == 1) return sL;
fusionSort_State(sL);
ListNode* curr = sL->head;
State* state1 = NULL;
State* state2 = NULL;
//SIMILAR t
while (curr != NULL && curr->next != NULL) {
state1 = (State*)curr->data;
state2 = (State*)curr->next->data;
//Current and following element considered as duplicate
if (state1->_t == state2->_t) {
//Remove bad duplicate
if (state1->_eOe <= state2->_eOe)
removeData(state2, sL);
else
removeData(state1, sL);
}
//Next duplicate group
else curr = curr->next;
}
return sL;
}
//Summ of _dur
double sumDurTaskList(ListNode* tL) {
if (tL == NULL) return NULL;
Task* task = (Task*)tL->data;
if (tL->next == NULL) return task->_dur;
return task->_dur + sumDurTaskList(tL->next);
}
//Describe a list of state
std::string listToString_State(List* sL) {
if (sL == NULL) return "List : [ NOT INITIALIZED ].\n";
if (sL->size == 0) return "List : [ EMPTY ].\n";
if (sL->size == 1) return "START OF LIST OF STATE : [ " + stateToString((State*)sL->head->data) + " ]. END OF LIST OF STATE\n";
ListNode* curr = sL->head;
std::string st = "START OF LIST OF STATE : [\n ";
while (curr != NULL) {
st += stateToString((State*)curr->data);
if (curr->next != NULL) st += "\n \n";
curr = curr->next;
}
return st + " \n]. END OF LIST OF STATE \n \n \n";
}
//Describe a list of task
std::string listToString_Task(List* tL) {
if (tL == NULL) return "List : [ NOT INITIALIZED ].\n";
if (tL->size == 0) return "List : [ EMPTY ].\n";
if (tL->size == 1) return "START OF LIST OF TASK : [ " + taskToString((Task*)tL->head->data) + " ]. END OF LIST OF TASK\n";
ListNode* curr = tL->head;
std::string st = "START OF LIST OF TASK : [ \n";
while (curr != NULL) {
st += taskToString((Task*)curr->data);
if (curr->next != NULL) st += "\n";
curr = curr->next;
}
return st + "\n]. END OF LIST OF TASK\n \n \n";
}
//Describe a list of taskpair
std::string listToString_TaskPair(List* tL) {
if (tL == NULL) return "List : [ NOT INITIALIZED ].\n";
if (tL->size == 0) return "List : [ EMPTY ].\n";
if (tL->size == 1) return "START OF LIST OF TASKPAIR : [ " + taskPairToString((TaskPair*)tL->head->data) + " ]. END OF LIST OF TASKPAIR\n";
ListNode* curr = tL->head;
std::string st = "START OF LIST OF TASKPAIR : [ \n";
while (curr != NULL) {
st += taskPairToString((TaskPair*)curr->data);
if (curr->next != NULL) st += "\n";
curr = curr->next;
}
return st + "\n]. END OF LIST OF TASKPAIR\n \n \n";
}
// -----------------------------------------------------//
// ------------------ FPTAS TOOLS ------------------//
// -----------------------------------------------------//
//All Task on machine 2, Tasks sorted by decreasing order of latency
State* heuristic(List* l) {
//Copy list to not modify original instance
List* copyL = consList();
newCopy(l->head, copyL);
//Sort by decreasing order
fusionSort_Task(copyL);
ListNode* curr = copyL->head;
Task* currT = (Task*)curr->data;
//Heuristic's result
State* H = consState();
double temp_t = 0;
double temp_q = 0;
//Placed Task total duration
double Ak = 0;
//Heuristic
while (curr != NULL) {
temp_t = Ak / 2 + (currT->_dur / 2);
temp_q = fmax(temp_t + currT->_lat, H->_eOe);
H->_eOe = temp_q;
append(currT, H->_task2);
Ak += currT->_dur;
curr = curr->next;
}
return H;
}
//Return the delta value for duration
double findDeltaD(List* l, double sigma) { return (sigma*sumDurTaskList(l->head)) / (4 * l->size); }
//Return the delta value for latency
double findDeltaL(List* l, double sigma) {
List* copyL = consList();
newCopy(l->head, copyL);
return (sigma*heuristic(copyL)->_eOe) / (6 * l->size);
}
//Round duration depending on deltaD and latency depending on deltaL || Create a new list
List* rounding(List* taskList, double deltaD, double deltaL) {
//Current node
ListNode* curr = taskList->head;
//Current task
Task* currT = NULL;
//Rounded task
Task* newT = NULL;
//Rounded task list
List* l = consList();
if (taskList->size == 1) {
currT = (Task*)curr->data;
newT = consTask(std::ceil(currT->_dur / deltaD) * deltaD, std::ceil(currT->_lat / deltaL) * deltaL);
push(newT, l);
return l;
}
while (curr != NULL) {
currT = (Task*)curr->data;
newT = consTask(std::ceil(currT->_dur / deltaD) * deltaD, std::ceil(currT->_lat / deltaL) * deltaL);
append(newT, l);
curr = curr->next;
}
return l;
}
//Create a new list pairing the corresponding original and rounded Tasks
List* createListTaskPair(List* origin, List* rounded) {
//Paired list
List* pairL = consList();
ListNode* currO = origin->head;
ListNode* currR = rounded->head;
TaskPair* pair = NULL;
while (currO != NULL) {
//Create pair
pair = consTaskPair((Task*)currO->data, (Task*)currR->data);
//Add pair
append(pair, pairL);
//Next value
currO = currO->next;
currR = currR->next;
}
return pairL;
}
//Transpose Optimal Solution of a rounded instance to it's original instance
State* transpose(State* opt, List* taskPair){
//Transposed State || result
State* trueOpt = consState();
ListNode* currStateTask1 = opt->_task1->head;
ListNode* currStateTask2 = opt->_task2->head;
ListNode* currPair = taskPair->head;
//Placed Task total duration
double Ak = 0;
//Transpose Machine 1 Task
while (currStateTask1 != NULL) {
//Current Task
Task* currT = (Task*)currStateTask1->data;
bool found = false;
TaskPair* currP = NULL;
//Search in Pairs
while (!found) {
currP = (TaskPair*)currPair->data;
if (currT == currP->_rounded) found = true;
else currPair = currPair->next;
}
//Add Task to transposed State
append(currP->_origin, trueOpt->_task1);
//Add Task duration to _t
trueOpt->_t += currP->_origin->_dur;
//Define new _eOe
trueOpt->_eOe = fmax(trueOpt->_t + currP->_origin->_lat , trueOpt->_eOe);
//Remove Task to speed up next research
removeData(currP, taskPair);
//Reinitialize to head
currPair = taskPair->head;
//Next Task to transpose
currStateTask1 = currStateTask1->next;
}
//Only Machine 1 execution
Ak = trueOpt->_t;
//Transpose Machine 2 Task
while (currStateTask2 != NULL) {
//Current Task
Task* currT = (Task*)currStateTask2->data;
bool found = false;
TaskPair* currP = NULL;
//Search in Pairs
while (!found) {
currP = (TaskPair*)currPair->data;
if (currT == currP->_rounded) found = true;
else currPair = currPair->next;
}
//Add Task to transposed State
append(currP->_origin, trueOpt->_task2);
//Define new _eOe
trueOpt->_eOe = fmax((Ak - trueOpt->_t)/2 + currP->_origin->_dur/2 + currP->_origin->_lat, trueOpt->_eOe);
//Add curr Task time to Ak
Ak += currP->_origin->_dur;
//Remove Task to speed up next research
removeData(currP, taskPair);
//Reinitialize to head
currPair = taskPair->head;
//Next Task to transpose
currStateTask2 = currStateTask2->next;
}
return trueOpt;
}
// -----------------------------------------------------//
// ------------------ PROG DYN ALGO ------------------//
// -----------------------------------------------------//
//Use Dynamic Programmation based on States to find an Optimal Solution
State* progDynState(List* taskList) {
std::cout << "PROG DYN | State ==>> \n";
std::cout << "Task List :: \n" << listToString_Task(taskList) << "\n";
//Get-through list
ListNode * currT = taskList->head;
//Start state, (0 , 0 , 0 , 0)
State* start = consState();
//State list
List* sL = consList(); //Xi-1
push(start, sL);
List* sL2 = consList();//Xi
//Get through list
ListNode* currS = sL->head;
//Placed Task total duration
double Ak = 0;
while (currT != NULL) {
Task* ctask = (Task*)currT->data;
empty(sL2);
//Create new States with new Task and old States
while (currS != NULL) {
State* cstate = (State*)currS->data;
//std::cout << "MM |||| MM - Mother State : " << stateToString(cstate) << "\n\n";
//ON MACHINE 1
//new start, start of state + task duration
double temp_t = cstate->_t + ctask->_dur;
//max between (start of state + latency of task) and (end of original state)
double temp_q = fmax(temp_t + ctask->_lat, cstate->_eOe);
State * s1 = consState(temp_q, temp_t);
//Keep track of tasks on first machine
newCopy(cstate->_task1->head, s1->_task1);
append(currT->data, s1->_task1);
//Keep track of tasks on second machine
newCopy(cstate->_task2->head, s1->_task2);
//std::cout << "S1 |||| S1 - State 1 : " << stateToString(s1) << "\n\n";
//Add state to list
push(s1, sL2);
//ON MACHINE 2
//new start, start of state + task duration
temp_t = (Ak - cstate->_t) / 2 + (ctask->_dur / 2);
//max between (start of state + latency of task) and (end of original state)
temp_q = fmax(temp_t + ctask->_lat, cstate->_eOe);
State * s2 = consState(temp_q, cstate->_t);
//Keep track of tasks on second machine
newCopy(cstate->_task2->head, s2->_task2);
append(currT->data, s2->_task2);
//Keep track of tasks on first machine
newCopy(cstate->_task1->head, s2->_task1);
//std::cout << "S2 |||| S2 - State 2 : " << stateToString(s2) << "\n\n";
//Add state to list
push(s2, sL2);
//Next list member
currS = currS->next;
}
//Xi CREATED
//ERASE OLD SET OF STATE --- Xi-1
freeNodes(sL);
//SET IT ANEW --- Xi-1 = Xi
assignTo(sL, sL2);
//OPTIMIZATION
//Removes multiple occurence of t value, only keeping the best of each.
sL = removeMultOcc(sL);
//Keeps best state
//sL = keepBestState(sL);
currS = sL->head;
//END OF OPTIMIZATION
//Add curr Task time to Ak
Ak += ctask->_dur;
//Next list member
currT = currT->next;
}
//std::cout << "Best States : \n" << listToString_State(sL) << " \n\n";
sL = keepBestState(sL);
std::cout << "Optimal Solution : \n" << stateToString((State*)sL->head->data) << " \n";
return (State*)sL->head->data;
}
#endif // !TOOLS
我的代码有什么问题?
我的内存管理似乎有些问题,但我找不到在哪里。我非常感谢您的帮助!我正在使用 Visual Studio 2019。
解决方案
推荐阅读
- delphi - delphi 的 mdi 父窗体中的“OnMouseWheel”事件时无法滚动
- python - 当 Sublime 在 Windows 上并且 Python 在 Ubuntu 上时如何使 Sublime 的 python 解释器工作
- python-3.x - 使用数据框查找另一个数据框
- asynchronous - 在超时后取消 LoadAsync 操作并在之后调用 LoadAsync 会引发异常
- javascript - 检查对象是否为数组中的特定值
- wpf - 设置绑定到字典的 WPF ComboBox 的任意值
- java - 如何在 Spring 将其反序列化为 POJO 之前访问原始请求有效负载?
- python - 如何在python中将矩阵的数量转换为分数而不是小数?
- javascript - 编辑文本区域后 jQuery 追加不起作用
- android - 在android studio的googlemap上显示错误的位置