Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
Error - *** error for object 0x7ffeefbff360: pointer being freed was not allocated.
I understand its better to use vectors, but our prof wants us to use it this way.
My unwrap function is giving me errors where I want to release the memory, also when I want to print the pattern using the for loop in the display function it gives me a garbage value out of memory instead of printing out the pattern itself. I tested using cout in the wrap function and it works there but not in my display function.
bool wrap(Gift& theGift){
if (theGift.m_wrap == nullptr) {
cout << "Wrapping gifts..." << endl;
do {
cout << "Enter the number of wrapping layers for the Gift: ";
cin >> theGift.m_wrapLayers;
}while ((theGift.m_wrapLayers <= 0) && cout << "Layers at minimum must be 1, try again." << endl);
theGift.m_wrap = new Wrapping[theGift.m_wrapLayers];
char buffer[100];
int patternLength;
for (int i = 0; i < theGift.m_wrapLayers; i++) {
cout << "Enter wrapping pattern #" << i + 1 << ": ";
cin >> buffer;
patternLength = (unsigned)strlen(buffer);
theGift.m_wrap[i].m_pattern = new char[patternLength + 1];
theGift.m_wrap[i].m_pattern = buffer;
cout << theGift.m_wrap[i].m_pattern << endl;
}
return true;
}else {
cout << "Gift is already wrapped!" << endl;
return false;
}
}
bool unwrap(Gift& theGift){
if (theGift.m_wrap != nullptr) {
cout << "Gift being unwrapped." << endl;
for (int i = 0; i < theGift.m_wrapLayers; i++) {
delete[] theGift.m_wrap[i].m_pattern;
theGift.m_wrap[i].m_pattern = nullptr;
}
delete[] theGift.m_wrap;
theGift.m_wrap = nullptr;
return true;
}else{
cout << "Gift isn't wrapped! Cannot unwrap." << endl;
return false;
}
}
void display(Gift& theGift){
cout << "Gift Details: " << endl;
cout << " Description: " << theGift.m_description << endl;
cout << " Price: " << theGift.m_price << endl;
cout << " Units: " << theGift.m_units << endl;
cout << "Wrap Layers: " << theGift.m_wrapLayers << endl;
for (int i = 0 ; i < theGift.m_wrapLayers; i++) {
cout << "Wrap #" << i + 1 << " ->" << theGift.m_wrap[i].m_pattern << endl;
}
}
Error - *** error for object 0x7ffeefbff360: pointer being freed was not allocated.
in wrap :
char buffer[100];
...
theGift.m_wrap[i].m_pattern = buffer;
you save in the in-out parameter theGift a pointer to the local array buffer (and you have a memory leak for the lost of the allocation done in theGift.m_wrap[i].m_pattern = new char[patternLength + 1]; just before)
and later in unwrap :
delete[] theGift.m_wrap[i].m_pattern;
you try to delete that invalid pointer.
In fact in wrap rather than :
theGift.m_wrap[i].m_pattern = new char[patternLength + 1];
theGift.m_wrap[i].m_pattern = buffer;
you wanted to do :
theGift.m_wrap[i].m_pattern = new char[patternLength + 1];
strcpy(theGift.m_wrap[i].m_pattern, buffer);
Note you can also use std::string for m_pattern rather than array of char, and a std::vector<Wrapping>for m_wrap rather than an array of Wrapping. That simplify a lot, no new nor delete
Related
I'm having trouble getting the size of a vector by dot-walking from a parent vector into the one in question. I have verified that calling the function myfunc 1 2 3 4 5 creates five Person objects and puts them in the left vector. But when I try to get that same size to return by dot-walking from bridge to left, I get 0 as the size.
What am I doing wrong?
int main(int argc, char* argv[]) {
Person* p_ptr;
int id_source = 0;
vector<Person> left;
vector<Person> right;
bridge.push_back(left);
bridge.push_back(right);
cout << "bridge.size() = " << bridge.size() << endl;
for (int i = 1; i < argc; i++) {
id_source++;
cout << "Creating Person with crossing speed of " << argv[i] << " and id of " << id_source << endl;
p_ptr = new Person(atoi(argv[i]), id_source);
left.push_back(*p_ptr);
}
/*SIZE TESTING*/
cout << "Left side of bridge has " << left.size() << " people on it " << endl;
cout << "bridge.at(0).size() = " << bridge.at(0).size() << endl;
cout << "bridge.at(1).size() = " << bridge.at(1).size() << endl;
int slowest_id = get_slowest(0);
for (int i = 0; i < left.size(); i++) {
if (slowest_id == left.at(i).get_id()) {
p_ptr = &left.at(i);
}
}
cout << "The slowest person has id of " << slowest_id << " and speed of " << p_ptr->get_crossing_time() << endl;
}
}
left and bridge[0] are two different lists. When you call bridge.push_back(left) you make a copy of the current left list (which is empty). Elements added later will not be in the bridge version.
This question already has answers here:
Pointer errors in the method of transmission(c++)
(4 answers)
Closed 8 years ago.
Question: I can't seem to set a pointer to an address that was created inside of a function. It always gets set to Null, how do I fix this?
Problem: I believe the problem is caused by the variable being created inside of another function. What's happening is that after the function executes, the pointer is set to NULL again.
Code:
void listAdd(int *list, int &length) {
int* tempList = new int[ length + 1 ];
for( int i = 0; i < length; i ++ )
{
(tempList)[ i ] = (list)[ i ];
}
cout << " Previous adress: " << hex << list << endl;
if ( list != NULL )
delete[] list;
list = new int[ length + 1 ];
cout << " New address: " << hex << list << endl << dec;
for( int i = 0; i < length; i ++ )
{
(list)[ i ] = (tempList)[ i ];
}
delete[] tempList;
cout << " Enter a number: ";
int stored = 0;
cin >> stored;
(list)[length -1] = stored;
length ++;
cout << " Length: " << length << "\n";
cout << " value at array point 0: " << (list)[length -1];
cout << "\n retry " << (list)[length-1] <<"\n";
cout << "\n \n \n This is pointing to 0x" << hex << list << '\n' << flush;
}
It seems you would like the changes to list to be valid after the function returned: since list is passed by value, the object manipulated inside the function happens to be a copy of the one you passed in. You probably either want to pass the object by reference, i.e.:
void listAdd(int*& list, int &length) {
// ...
}
... or return the result
int* listAdd(int* list, int& length) {
// ...
return list;
}
list = listAdd(list, length);
Well, realistically, you really really want to encapsulate the objects in a class or just use std::vector<int>.
I have this vector class, and I was provided with a driver to test the class. Most of it seems to work fine but I think there is something wrong with the exceptions part (which I haven't quite fully understood)
Here is the code for the class .cpp file
int myVector::at(int i)
{
if(i<vsize)
return array[i];
throw 10;
}
and here is the driver code
#include "myVector.h"
#include <iostream>
using namespace std;
int main()
{
// Create a default vector (cap = 2)
myVector sam;
// push some data into sam
cout << "\nPushing three values into sam";
sam.push_back(21);
sam.push_back(31);
sam.push_back(41);
cout << "\nThe values in sam are: ";
// test for out of bounds condition here
for (int i = 0; i < sam.size( ) + 1; i++)
{
try
{
cout << sam.at(i) << " ";
}
catch(int badIndex)
{
cout << "\nOut of bounds at index " << badIndex << endl;
}
}
cout << "\n--------------\n";
// clear sam and display its size and capacity
sam.clear( );
cout << "\nsam has been cleared.";
cout << "\nSam's size is now " << sam.size( );
cout << "\nSam's capacity is now " << sam.capacity( ) << endl;
cout << "---------------\n";
// Push 12 values into the vector - it should grow
cout << "\nPush 12 values into sam.";
for (int i = 0; i < 12; i++)
sam.push_back(i);
cout << "\nSam's size is now " << sam.size( );
cout << "\nSam's capcacity is now " << sam.capacity( ) << endl;
cout << "---------------\n";
cout << "\nTest to see if contents are correct...";
// display the values in the vector
for (int i = 0; i < sam.size( ); i++)
{
cout << sam.at(i) << " ";
}
cout << "\n--------------\n";
cout << "\n\nTest Complete...";
cout << endl;
system("PAUSE");
return 0;
}
Any help is appreciated. Thanks
The driver that you have provided:
try {
cout << sam.at(i) << " ";
}
catch(int badIndex) {
cout << "\nOut of bounds at index " << badIndex << endl;
}
expects that int will be thrown (a bit weird design, but well... this is the code that will use your class...). Your implementation of at() might look like this:
int& myVector::at(int i) throw(int) {
if (i < vsize)
return array[i];
throw i;
}
just try to follow one simple rule: throw by value, catch by reference.
Also note that you have a pointer:
private:
int* array;
which points to dynamically allocated memory allocated in constructor and copy constructor and freed in destructor :
myVector::myVector(int i)
{
...
array = new int[maxsize];
}
myVector::myVector(const myVector& v)//copy constructor
{
...
array =new int[maxsize];
}
myVector::~myVector()
{
delete[] array;
}
But how about the assignment operator ? See What is The Rule of Three?
Your stop condition of for loop ends it one element after the last one (i.e. you cannot access 4th element of sam vector because there are only three elements).
std::vector::at throws std::out_of_range exception in such situation (see: http://en.cppreference.com/w/cpp/container/vector/at), not int one. So you should change your exception handling part to something like this:
#include <exception>
try
{
cout << sam.at(i) << " ";
}
catch(std::out_of_range exc)
{
cout << "\nOut of bounds at index " << exc.what() << endl;
}
This is a part of my program while I run this program I get a segmentation fault. I've narrowed it down to the line:
checkBase(ptr1, ptr2)
i'm passing both of these as pointers. and they are declare as char* and its a runtime error not compile time.
file contains
< a href = "http://www.google.com"> www.spam.google.com < /a >
in this case ptr1 = www.google.com and ptr2 = spam.google.com
while(inf){
count++;
getline(inf, line);
//cout << "*******" << count << "*******" << endl <<line << endl;
p = new char[line.length()+1];
strcpy(p, line.c_str());
if(strstr(p, "href")){
ptr = strstr(p, "href");
while(ptr[0]!='\0'){
ptr += 1;
if(ptr[0] == 'w' && ptr[1] == 'w' && ptr[2] == 'w'){
cout << ptr << endl;
ptr = strtok(ptr, "\"");
cout << "add1 " << ptr << endl;
add1 = ptr;
ptr1 = ptr;
ptr = strtok(NULL, "> ");
add2 = ptr;
ptr2 = ptr;
cout << "ptr1: " << ptr1 << endl << "ptr2: " <<ptr2 << endl;
if(add1 == add2)
cout << "There is an exact match at line: " << count << endl << line << endl;
else{
cout << "in else" << endl;
checkBase(ptr1, ptr2); //THIS GIVES A SEGMENTATION FAULT
}
}
}
}
}
void checkBase(char *add1, char *add2){
cout << "here" << endl;
char *base1[1000000], *base2[1000000];
int count1 = 0, count2 = 0;
base1[count1] = strtok(add1, ".");
while(base1[count1] != NULL){
count1++;
base1[count1] = strtok(NULL, ".");
cout << base1[count1] << endl;
}
base2[count2] = strtok(add2, ".");
while(base2[count2] != NULL){
count2++;
base2[count2] = strtok(NULL, ".");
}
cout << base2[count2-1] << endl;
if(((strcmp(base1[count1-1],base2[count2-1])) != 0) && (strcmp(base1[count1-2], base2[count2-2]) != 0)){
//if((strcmp(base1[count1-1], base2[count2-1]) != 0)){
cout << "Bases do not match: " << endl
<< base1[count1-2] << "." << base1[count1-1] << " and "
<< base2[count2-2] << "." << base2[count2-1] << endl;
//}
}
else{
cout << "Bases match: " << endl
<< base1[count1-2] << "." << base1[count1-1] << " and "
<< base2[count2-2] << "." << base2[count2-1] << endl;
}
}
I have no idea why this is giving a segmenation fault.
char *base1[1000000], *base2[1000000];
No doubt this is causing stack overflow. The stack is limited in size, and creating arrays more than a few kb in size is a bad idea. Try allocating them on the heap, for example vector<char *> base1(1000000)
You should also calculate the exact size required and allocate that much, or push_back on the vector.
A couple of problems, beyond the stack overflow already mentioned by #Neil Kirkwell
Those shouldn't be while loops solely conditioned on base1[count1] != NULL; you should also make sure count1 is less than the number of elements in the array.
If either count2 or count1 is 0 or 1 you will be trying to reference index of -1 and -2... not so good.
use strrchr to search backwards and make your life easier
It's wasteful to build those arrays entirely, since you only seem to care about the last two tokens, you only need two pointers in each.
i.e.
char *one_a = NULL, *one_b = NULL, *two_a=NULL, *two_b = NULL;
char *temp = strtok(add1, ".");
while (temp) {
one_b = one_a;
one_a = temp
temp = strtok(NULL, ".");
}
char *temp = strtok(add2, ".");
while (temp) {
two_b = two_a;
two_a = temp
temp = strtok(NULL, ".");
}
//now just compare one_a with two_a and one_b with two_b and you're done.
Could you have a look at what I've faced: http://sdrv.ms/WgafvN
And another screenshot: http://sdrv.ms/UZIp6H
The text of my function is:
bool print_all_points(POINT** pointer)
{
if (pointer == NULL||is_array_empty(pointer))
{
cout << "The array of points is empty." << endl << endl;
return false;
}
else
{
int n = _msize(pointer)/sizeof(pointer[0]);
cout << "The list of points: " << endl<< endl;
cout << "id (x, y)" << endl;
cout << "----------" << endl;
for (int i = 0; i < n; i++)
{
cout << (*pointer[i]).id << " (" << (*pointer[i]).x << ", " << (*pointer[i]).y << ")" << endl;
}
}
return true;
}
This function is expected to print out all the points in an array. My problem is that it perfectly prints the array of 3 points rather than that of 4 points. At the 4th point it bites the dust.
I can't catch what the trouble is.
From the picture it is visible that:
1. All 4 elements of the array are present.
2. It is correctly determined that there 4 of them.
What is the problem?
Could you give me a kick here?
ADDED LATER.
The function which calls this:
POINT** new_point(POINT** pointer, int occup)
{
char x;
char y;
system("cls");
cout << "INPUT A NEW POINT" << endl << endl;
cout << "Input x: ";
cin >> x;
cout << "Input y: ";
cin >> y;
size_t m;
if (pointer != NULL)
{
m = _msize(pointer);
}
POINT * tmp_point = new POINT();
(*tmp_point).id = occup;
(*tmp_point).x = x-48;
(*tmp_point).y = y-48;
POINT** pn = new POINT * [occup];
int necessary_memory = occup * 4; // ???? 4 is the size of a pointer.
if (occup !=1)
{
memcpy(pn, pointer, necessary_memory);
}
POINT ** tmp = new POINT * [occup];
pn[occup - 1] = tmp_point;
memcpy(tmp, pn, occup * sizeof(POINT));
delete[] pn;
pn = tmp;
size_t n = _msize(pn);
cout << endl;
print_all_points(pn);
return pn;
}
several problems:
not copying enough data in 64-bit
int necessary_memory = occup * 4;
should be
int necessary_memory = occup * sizeof(POINT*);
copying too much data
memcpy(tmp, pn, occup * sizeof(POINT));
should be:
memcpy(tmp, pn, occup * sizeof(POINT*));
Someone else can chime in, but I am not sure _msize should be used on memory allocated by new. Is that right? http://msdn.microsoft.com/en-us/library/z2s077bc(v=vs.80).aspx
fucntion in the title should be function
You're welcome. You owe me a beer.
Oh yea, I found my shoes... where would you like it?