Was writing some code for an assignment to take integers as input and place them in an array to be printed.
I'm cleaning up all of my pointers as far as I can tell but I keep getting the runtime error:
1 [main] new 3444 cygwin_exception::open_stackdumpfile: Dumping stack trace to new.exe.stackdump
body of code:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int array[10];
int * p = array;
int *readNumbers()
{
int i=0;
for(i=0;i<10;i++)
{
string number;
int numb;
cout << "enter digit " << i << " of 10" << endl;
getline(cin, number);
istringstream (number) >> numb;
array[i]=numb;
}
return p;
delete p;
}
void printNumbers(int *numbers,int length)
{
int i;
for(i=0;i<length;i++)
{
cout << i << " " << *(numbers+i) << endl;
}
}
and the main calling code:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
extern int *readNumbers();
extern void printNumbers(int *,int);
int main()
{
int * q = readNumbers();
printNumbers(q,10);
delete q;
return 0;
}
So just looking for a solution to the stack dump...
Also I'm sure the method I used to apply the string number returned by cin to the values contained in array[10] is not what the question was looking for so any notes on that would be great.
Thanks
It is not a good practice to return a pointer to a memory allocated inside a function, in this case, you are not even allocating it inside a function, you have done it in a global space.
It is a good practice to activate all your warnings during the compile, even treat them as error when you are doing an assignment.
As a tip, you can allocate the memory in your main function and then pass the pointer to the readNumbers function.T This way it remains inside the same scope and it is easier to manage.
also, the same way you pass the lenght of the array to the printnumbers function you should pass it to the readnumbers one instead of hardcoding it.
Your delete are invalid, you can only delete something you've allocated with new.
The first one is harmless because it's after a return, so never executed (BTW you should look at compiler warnings).
The second one might produce your crash.
Also I'm sure the method I used to apply the string number returned by cin to the values contained in array[10] is not what the question was looking for so any notes on that would be great.
That's OK. What's dubious is spreading the size of the array everywhere, what happens if you want to change it ?
Related
I am trying to program my own hangman game without refrencing other programs as a way to get back into programming.
Right now I am trying to program a structure that will hold all of the letters that will be alphabetized and displayed for the user. In the middle of trying to realloc i got this error
34 67 C:\Users\hanna\Documents\C Codes\Testing Hangman.cpp [Error] invalid conversion from 'void*' to 'Guess*' [-fpermissive]
Here is the code I am working with right now:
#include <ctime>
#include <stdio.h>
#include <iostream>
#include<stdlib.h>
#include <cstdlib> //has rand function
using std::cout;
using std::cin;
struct Guess {
char Letter[1];
};
int count = 0;
struct Guess*guessKeeper;
int main()
{
char choice;
cout << "Do you want to add another guess? \n";
cin >> choice;
cout << choice << "\n";
if (choice == 'y')
{
struct Guess newGuess;
cout << "What is your guess? \n";
cin >> newGuess.Letter;
guessKeeper = realloc(guessKeeper,(count+1)*sizeof(struct Guess));
count++;
guessKeeper[count-1] = newGuess;
cout << "Do you want to add another guess? \n";
cin >> choice;
};
free(guessKeeper); //Free Memory
}
Any recomendations on how to alphabetize would also be appretiated.
I have tried refrencing other online tutorials and some of my old code from my college classes; it is why I landed on structures as I have an old assignment that had used a structure and has code for alphabetizing I was hoping to refrence.
In C++ opposite to C you may not assign a pointer of the type void * to a pointer to an object type. You need to cast the return value of calls of for example realloc or malloc to the destination pointer type.
For example
guessKeeper = static_cast<Guess *>( realloc(guessKeeper,(count+1)*sizeof(struct Guess)) );
And in C++ you should use operators new and delete instead of realloc and free,
Also these statements in the end of the if statement
cout << "Do you want to add another guess? \n";
cin >> choice;
does not make sense because there is no loop in the program.
And this semicolon that defines a null-statement
//...
};
is redundant. Remove it.
And leave only the second include among these two includes
#include<stdlib.h>
#include <cstdlib> //has rand function
And remove this include
#include <stdio.h>
Also as correctly pointed #Blindy this declaration of the data member of an array type with one element does not make sense
struct Guess {
char Letter[1];
};
because this statement
cin >> newGuess.Letter;
results in memory corruption. That is it will try to read a string instead of a single character.
Instead you could declare the structure like for example
struct Guess {
char Letter;
};
I need someone to solve the problem which is a question of dynamic memory allocation and
dynamic deallocation.
Here's a part of code to create database
include <iostream>
#include <string>
using namespace std;
struct subject {
string subname;
int score;
string grade;
float gpa;
};
struct student {
string stuname;
int stunum;
int subnum;
subject *sub;
float avegpa = 0;
};
int main(void){
int i = 0;
cout << "Put number of students : ";
cin >> i;
student* p = new student[i];
.
.
.
delete p->sub;
delete[] p;
return 0;
}
here's my desired result
Now, I have to enter the value of i first, but I hope I can automatically set
the value of i.
In order to try number 1, I pushed back value of i and increased i, but there was an
error. I don't know why.
This is the error message from number 2.
C++ crt detected that the application wrote to memory after end of heap buffer
delete p->sub;
You never initialised p[0].sub. Deleting (or even reading) an uninitialised pointer will result in undefined behaviour. You may delete only what you new.
P.S. Owning bare pointers are a bad idea. I recommend using std::vector to manage dynamic arrays.
I'm trying to create an array and the size of the array depends on the user input. But there is an error in my code, It said: "expression must have a constant value".
Here is my code:
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int var;
cout << "What size do you want to choose: "<< endl;
cin >> var;
int arr[var];
}
How can I change my code and make it work?
How can I change my code and make it work?
Change
int arr[var];
to
std::vector<int> arr(var);
This will require #include <vector>
The syntax you are using is known as a "variable length array", and is NON-STANDARD. Only a few compilers support it as an vendor-specific extension to the C++ language.
A standard compliant fixed-length array must have its size known to the compiler as a compile-time constant.
For what you want, you need to use the new[] operator instead:
int *arr = new int[var];
...
delete[] arr;
Or better, use a std::vector container:
#include <vector>
std::vector<int> arr(var);
To allocate an array dynamically, we use the array form of new and delete (often called new[] and delete[]):
#include <iostream>
int main()
{
std::cout << "Enter a positive integer: ";
int length{};
std::cin >> length;
int *array{ new int[length]{} }; // use array new. Note that length does not need to be constant!
std::cout << "I just allocated an array of integers of length " << length << '\n';
array[0] = 5; // set element 0 to value 5
delete[] array; // use array delete to deallocate array
// we don't need to set array to nullptr/0 here because it's going to go out of scope immediately after this anyway
return 0;
}
Arrays in C++ must have constant size known at compile-time. You can preallocate several constant sizes known at compile time and offer the user to choose one of them. Alternatively, you can use another data structure that allows dynamic size allocation e.g std::vector.
Good luck!
I have got class "student.cpp"
#include <iostream>
#include "student.h"
using namespace std;
void student::setMarks(int m1, int m2) {
mark1 = m1;
mark2 = m2;
};
void student::setName(char *n) {
name = n;
};
int student::calc_media(void){
return (mark1+mark2)/2;
};
void student::disp(void){
cout << "Student:" << name << " \n media:"<< calc_media() <<"\n";
};
student::student(){
mark1 = 0;
mark2 =0;
name = "";
};
Header file "student.h":
ifndef CLASY_STUDENT_H
#define CLASY_STUDENT_H
#endif //CLASY_STUDENT_H
class student{
char *name;
int mark1, mark2;
public:
void setName(char *n);
void setMarks(int m1, int m2);
void disp(void);
int calc_media(void);
student();
};
And "main.cpp":
#include <iostream>
#include "student.h"
using namespace std;
int main() {
student s;
char* n;
int m1, m2;
cout << "Enter name:";
cin>> n;
cout << "Enter marks of two subjects:";
cin>> m1;
cin>> m2;
s.setName(n);
s.setMarks(m1, m2);
s.disp();
return 0;
}
I am running this usign Clion and Cmake is :
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
set(SOURCE_FILES main.cpp student.cpp student.h student.cpp student.h)
But when I run, it asks for name, but when I type something then I have got a memory fragmentation error. Whats wrong?
And could someone by the way tell me if it looks okey for C++? I am trying to switch from java to c++.
char* n;
...
cin>> n;
n is a pointer, supposed to point at a particular piece of memory. But you never set it. So it has some undefined value, pointing who-knows-where into some memory that you end up trying to overwrite. Most likely memory you are not allowed to overwrite, causing a segfault.
Don't try to use char* if you don't yet know about manual memory management (and once you do, you'll understand why not to). Use std::string.
From a quick glance, you can pretty much replace char* everywhere with std::string (as long as you #include <string>).
Similar to what others are saying, your variable n is an uninitialized pointer. Pointers, as the name suggests, are just signposts to a particular location in memory - the tell the CPU "go to this memory location for variable x".
Say you have an integer variable var, which is declared like this:
int var;
That variable occupies memory and you can assign it a value like this:
var = 5;
You can also declare a pointer to an integer like this:
int * var_ptr;
Now assuming var_ptr points to a valid integer I can assign a value to it like this:
*var_ptr = 5;
This says "put the number 5 at the memory location pointed to by var". However if var_ptr has not been initialized then it will point to a random location in memory that may overwrite something important, or attempt to write to a protected memory address causing a protection fault (segfault). This is what is happening in your code.
To initialize var_ptr to point to the address of var, we can do this:
var_ptr = &var;
The ampersand is the "address of" operator - it says "don't get me the value of var but instead get me the address of the memory location where var is stored".
So, to prevent your problem, you must initialize n to some valid memory location where you are able to safely write some data.
There are a few ways to do this. As #Stefan points out you can declare n to be a character array:
char n[20];
As #BobTFish points out you need some way to make sure that your input doesn't exceed the size of your array (20 bytes in this case). The solution is std::cin.width(20).
As #BobTFish also mentions, you could also using a std::string, like this:
std::string n;
std:cin >> n;
The std::string object will automatically take care of memory allocation.
If you really must use a char *, you can either take the address of a char array (here I take the address of the first element of the array):
char n_array[20];
char *n = &n_array[0];
std::cin.width(20);
std::cin >> n;
You could also use dynamic memory allocation:
char *n = new char[20];
std::cin.width(20);
std::cin >> n;
delete n;
Notice that if you use dynamic memory allocation you must free the memory using delete when you are done otherwise there will be a memory leak. Local variables (like the array) are allocated on the stack and therefore are automatically freed when the function returns. For this reason, and the overhead of dynamic memory allocation, you would be insane to use it here.
I am trying to return an array from a function:
#include <iostream>
using namespace std;
int* uni(int *a,int *b)
{
int c[10];
int i=0;
while(a[i]!=-1)
{
c[i]=a[i];
i++;
}
for(;i<10;i++)
c[i]=b[i-5];
return c;
}
int main()
{
int a[10]={1,3,3,8,4,-1,-1,-1,-1,-1};
int b[5]={1,3,4,3,0};
int *c=uni(a,b);
for(int i=0;i<10;i++)
cout<<c[i]<<" ";
cout<<"\n";
return 0;
}
I pass two arrays from my main() into my uni() function. There I create a new array c[10] which I return to my main().
In my uni() function I try to merge the non-negative numbers in the two arrays a and b.
But I get something like this as my output.
1 -1078199700 134514080 -1078199656 -1216637148 134519488 134519297 134519488 8 -1078199700
Whereas when I try to print the values of c[10] in the uni() function it prints the correct values. Why does this happen??
Is this something related to the stack?? Because I have tried searching about this error of mine, and I found a few places on stackoverflow, where it says that do not allocate on stack but I couldn't understand it.
Further it would become very easy if I allocate my array globally, but if this is the case then everything shall be declared globally?? Why are we even worried about passing pointers from functions?? (I have a chapter in my book for passing pointers)
Admittedly, the std::vector or std::array approach would be the way to go.
However, just to round things out (and if this is a school project, where the teacher gives you the obligatory "you can't use STL"), the other alternative that will avoid pointer usage is to wrap the array inside a struct and return the instance of the struct.
#include <iostream>
using namespace std;
struct myArray
{
int array[10];
};
myArray uni(int *a,int *b)
{
myArray c;
int i=0;
while(a[i]!=-1)
{
c.array[i]=a[i];
i++;
}
for(;i<10;i++)
c.array[i]=b[i-5];
return c;
}
int main()
{
int a[10]={1,3,3,8,4,-1,-1,-1,-1,-1};
int b[5]={1,3,4,3,0};
myArray c = uni(a,b);
for(int i=0;i<10;i++)
cout << c.array[i] << " ";
cout << "\n";
return 0;
}
Note that the struct is returned by value, and this return value is assigned in main.
You have the value semantics of returning an instance, plus the struct will get copied, including the array that is internal within it.
Live Example
You're returning a pointer to a local object. In the uni function, the variable c is allocated on the stack. At the end of that function, all of that memory is released and in your for loop you are getting undefined results.
As suggested in the comments, std::array or std::vector will give you copy constructors that will allow you to return the object by value as you're trying to do. Otherwise you'll have to resort to something like passing your output array in as an argument.
You are returning a pointer to an array that is being deallocated at the return statement. It's a dangling pointer. It's UB.
Use an std::vector or std::array and return by value. There are compiler optimizations that will avoid inefficiencies.