This may be very simple but I am confused!
I am getting segmentation fault when extracting information from a pointer to a pointer. See the cout section in main(). Any help will be appreciated.
Thanks..
Sen
#include <stdlib.h>
#include <iostream>
typedef struct{
int hour;
int minute;
} Time;
Time* GetNextTime(void)
{
Time *p_time = new Time;
return p_time;
}
void GetTime( Time **sometime )
{
int length = 10;
sometime = new Time*[length];
for(int i=0; i<length; i++)
{
sometime[i] = GetNextTime();
sometime[i]->hour = rand()%24 ;
sometime[i]->minute = rand()%60;
std::cout << "Entered times " << sometime[i]->hour << " hour " << sometime[i]->minute << " minutes " << std::endl;
}
}
int main()
{
Time** _time;
GetTime( _time );
//here is the question
// I cant print them from original _time
for( int i=0; i<10; i++)
std::cout << " Print times " << (*_time)[i].hour << " hour " << (*_time)[i].minute << " minutes " << std::endl;
}
You're passing sometime by value, not by reference so it remains uninitialized. Change GetTime to the following:
void GetTime( Time ** &sometime ) //& means pass by reference
Because you're creating an array of pointers, you can use array notation to access them during printing as well.
std::cout << " Print times " << _time[i]->hour << " hour "
<< _time[i]->minute << " minutes " << std::endl;
Unless an argument is explicitly labelled as using a reference it is passed by value in C++. Thus, assigning to sometime in GetTime() has no effect on _time in main().
My strong advice is not to us explict memory allocation but use containers, e.g. std::vector<T>, instead. You'd still need to pass the container by refernence, however.
In main
It should be
Time *_time;
GetTime(&_time)
And then cout should be done with _time instead of *_time
Related
This is FCFS cpu scheduling algorithm.
void findTurnAroundTime(int processes[], int n, int bt[], int wt[], int tat[])
{
// Calculating turnaround time by adding bt[i] + wt[i]
for (int i = 0; i < n; i++)
tat[i] = bt[i] + wt[i];
}
// Function to calculate average waiting and turn-around
// times.
void findavgTime(int processes[], int n, int bt[], int at[])
{
int wt[n], tat[n];
// Function to find waiting time of all processes
findWaitingTime(processes, n, bt, wt, at);
// Function to find turn around time for all processes
findTurnAroundTime(processes, n, bt, wt, tat);
// Display processes along with all details
cout << "Processes " << " Burst Time " << " Arrival Time "
<< " Waiting Time " << " Turn-Around Time "
<< " Completion Time \n";
int total_wt = 0, total_tat = 0;
for (int i = 0; i < n; i++)
{
total_wt = total_wt + wt[i];
total_tat = total_tat + tat[i];
int compl_time = tat[i] + at[i];
cout << " " << i + 1 << "\t\t" << bt[i] << "\t\t" << at[i] << "\t\t"
<< wt[i] << "\t\t " << tat[i] << "\t\t " << compl_time << endl;
}
cout << "Average waiting time = " << (float) total_wt / (float) n;
cout << "\nAverage turn around time = " << (float) total_tat / (float) n;
}
How are variables like wt and tat connected if they are decleared inside each function?(This is the main question)
full code is working.
How are variables like wt and tat connected if they are decleared inside each function?
wt and tat are defined in findavgTime. (They are defined using a non-standard extension but that's a separate issue).
When findavgTime calls findWaitingTime and findTurnAroundTime, it passes those variables to the functions. The functions don't define them in their function body -- they are defined in the functions by way of function arguments. Since wt and tat are arrays, they decay to a pointer to the first elements of the respective arrays when findWaitingTime and findTurnAroundTime are called. Because of that, any changes made to the variables inside those functions are visible in findavgTime too.
You don't have to use the same variable names in the function arguments. You could use
void findTurnAroundTime(int processes[], int n, int bt[], int wt_here[], int tat_here[])
{
for (int i = 0; i < n; i++)
tat_here[i] = bt[i] + wt_here[i];
}
That won't change the behavior of the program.
Here's the code:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int keyArray[7] = {1,2,3,4,5,6,7};
int breakPoint;
int counter;
for (counter = 0; counter < 7; counter++)
{
// keyArray[counter] = (rand() % 9) + 1; later
keyArray[counter] = counter; //testing
}
cout << keyArray[0] + "\n";
cout << keyArray[1] + "\n";
cout << keyArray[2] + "\n";
cout << keyArray[3] + "\n";
cout << keyArray[4] + "\n";
cout << keyArray[5] + "\n";
cout << keyArray[6] + "\n";
cin >> breakPoint; //so I can see what the hell is going on before it disappears
return 0;
}
The only reason I gave values to keyArray was that I read in answer to a similar question that you have to initialize an array with data before you use it. But it made no difference. The output is just junk symbols whether you initialize or not.
The compiler is Visual Studio Community 2017. Thanks for any help.
The error is not in your logic but rather in your debugging output. Since the other answers focus on how to fix it, I'll rather explain what happens instead. There seems to be a misunderstanding about the way strings work in C++.
The failure is in this operation:
keyArray[0] + "\n"
Internally, string literals are arrays of characters, in this case const char[2], consisting of the newline and a terminating '\0' null terminator. When you then try to add the integer and this array together, the array will be represented by a pointer to its first element, i.e. it will decay to const char* in order to be used as the second argument to the plus operator used in your code.
So for the compiler, this line will need operator+(int, const char*). But the result of that will be const char*, the input pointer offset by the integer, as that is the operation that happens when adding integers to pointers.
So instead of printing the number and then the string, it will try to access a string that does not exist as the pointer now pointer behind the string "\n" and thus into some arbitrary memory.
Instead of doing
cout << keyArray[0] + "\n"
do:
cout << keyArray[0] << "\n"
or
cout << keyArray[0] << endl
You can't concatanate an integer with a string. That's why you got garbage output
Try this first:
cout << keyArray[0] << "\n";
If you are using compilers that support C++ 11 then try using std::to_string(...) to make a string from an integer before doing the addition:
cout << (std::to_string(keyArray[0]) + "\n");
you cannot concatenate int with string.
change
cout << keyArray[0] + "\n";
cout << keyArray[1] + "\n";
cout << keyArray[2] + "\n";
cout << keyArray[3] + "\n";
cout << keyArray[4] + "\n";
cout << keyArray[5] + "\n";
cout << keyArray[6] + "\n";
to
cout << keyArray[0] << "\n"
<< keyArray[1] << "\n"
<< keyArray[2] << "\n"
<< keyArray[3] << "\n"
<< keyArray[4] << "\n"
<< keyArray[5] << "\n"
<< keyArray[6] << endl;
You need to convert the integers into a string. Using a relatively recent version of C++:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int keyArray[7] = {1,2,3,4,5,6,7};
int breakPoint;
int counter;
for (counter = 0; counter < 7; counter++)
{
// keyArray[counter] = (rand() % 9) + 1; later
keyArray[counter] = counter; //testing
}
cout << std::to_string(keyArray[0]) + "\n";
cout << std::to_string(keyArray[1]) + "\n";
cout << std::to_string(keyArray[2]) + "\n";
cout << std::to_string(keyArray[3]) + "\n";
cout << std::to_string(keyArray[4]) + "\n";
cout << std::to_string(keyArray[5]) + "\n";
cout << std::to_string(keyArray[6]) + "\n";
cin >> breakPoint; //so I can see what the hell is going on before it disappears
return 0;
}
I am doing a project named wireless Network Toplogy. It use graphs as a data structure. I have make pointers but am facing heap leak problems. Please can anyone help fix this error? Where to call the delete operator? The cpp code is attached:
#include <string>
#include <ctime>
#include <cstdlib>
#include <iostream>
#include "myGraph.h"
#include "wirelessNetwork.h"
using namespace std;
void main()
{
srand(time(NULL));
/* First part of the experiments */
for (int i = 500; i <= 950; i += 50)
{
wirelessNetwork *g = new wirelessNetwork(10, i);
std::cout << (L"For network with n=") << i << (L": ") << std::endl;
double average = (static_cast<double>(g->graph->numEdges) / (static_cast<double>(g->graph->numVertices)));
std::cout << (L" The average degree is ") << average << std::endl;
std::cout << (L" The maximum degree is ") << g->getMaxDegree() << std::endl;
/* Perform topology control */
g->topologyControl();
std::cout << (L" After topology control: ") << std::endl;
average = (static_cast<double>(g->graph->numEdges)) / (static_cast<double>(g->graph->numVertices));
std::cout << (L" The average degree is ") << average << std::endl;
std::cout << (L" The maximum degree is ") << g->getMaxDegree() << std::endl;
std::cout << std::endl;
}
/* Second part of the experiments */
wirelessNetwork *g = new wirelessNetwork(10, 1000);
std::cout << (L"***********************************") << std::endl;
for (int i = 1; i <= 10; i++)
{
/* Randomly pick two vertices as the source and destination */
int i1 = static_cast<int>(1000 * rand());
int i2 = static_cast<int>(1000 * rand());
string nameTemp = "a";
string node1 = nameTemp + std::to_string(i1);
string node2 = nameTemp + std::to_string(i2);
//ORIGINAL LINE: String[] route = g.compassRouting(node1, node2);
string *route = g->compassRouting(node1, node2);
std::cout << std::endl;
std::cout << (L"Path generated from ") << node1 << (L" to ") << node2 << (L":") << std::endl;
for (int k = 0; k < route->length(); k++)
{
std::cout << (L" ") << route[k];
}
if (node2 != route[route->length() - 1])
{
std::cout << std::endl;
std::cout << (L" No route found...") << std::endl;
}
std::cout << std::endl;
std::cout << (L" Length of the path generated is ") << (route->length() - 1) << std::endl;
}
/* Third part of the experiments */
g->topologyControl();
std::cout << std::endl;
std::cout << (L"***********************************") << std::endl;
std::cout << (L"After topology control...") << std::endl;
for (int i = 1; i <= 10; i++)
{
int i1 = static_cast<int>(1000 * rand());
int i2 = static_cast<int>(1000 * rand());
string nameTemp = "a";
string node1 = nameTemp + std::to_string(i1);
string node2 = nameTemp + std::to_string(i2);
//ORIGINAL LINE: String[] route = g.compassRouting(node1, node2);
string *route = g->compassRouting(node1, node2);
std::cout << std::endl;
std::cout << (L"Path generated from ") << node1 << (L" to ") << node2 << (L":") << std::endl;
for (int k = 0; k < route->length(); k++)
{
std::cout << (L" ") << route[k];
}
if (node2 != route[route->length() - 1])
{
std::cout << std::endl;
std::cout << (L" No route found...");
}
std::cout << std::endl;
std::cout << (L" Length of the path is ") << (route->length() - 1) << std::endl;
}
}
`
One way of identifying when to call delete operator is to check when that pointer variable goes out of scope and to delete it just before it goes out of scope.
void func()
{
ClassA* ptr1 = new ClassA;
//do NULL check for ptr1 and do stuff
delete ptr1;
//here ptr1 will lose scope.
//If not deleted, it will become a memory leak.
}
There can be scenarios where we cannot delete a pointer even if it goes out of scope. For example if we store the new pointer value in some other pointer variable, and the 2nd variable is still not out of scope.
void func(bool IsReady)
{
ClassA* ptr1 = NULL;
if(IsReady)
{
ClassA* ptr2 = new ClassA;
//do stuff
ptr1 = ptr2;
//in this case, even though ptr2 will lose scope outside this block,
//the ptr2 value is assigned to ptr1 which is does not lose scope outside this block.
}
//here ptr1 will still contain the data we copied in the if block,
//else it will be NULL. After use of ptr1 is complete, do a NULL check and delete.
if(ptr1 != NULL)
delete ptr1;
}
In your case I see only the first type, and only 2 places the new operator is called.
Have called the delete operator at the appropriate place for the first case, just before g goes out of scope:
/* First part of the experiments */
for (int i = 500; i <= 950; i += 50)
{
wirelessNetwork *g = new wirelessNetwork(10, i);
std::cout << (L"For network with n=") << i << (L": ") << std::endl;
double average = (static_cast<double>(g->graph->numEdges) / (static_cast<double>(g->graph->numVertices)));
std::cout << (L" The average degree is ") << average << std::endl;
std::cout << (L" The maximum degree is ") << g->getMaxDegree() << std::endl;
/* Perform topology control */
g->topologyControl();
std::cout << (L" After topology control: ") << std::endl;
average = (static_cast<double>(g->graph->numEdges)) / (static_cast<double>(g->graph->numVertices));
std::cout << (L" The average degree is ") << average << std::endl;
std::cout << (L" The maximum degree is ") << g->getMaxDegree() << std::endl;
std::cout << std::endl;
//here g loses scope and does not seem to be stored in any other pointer
delete g;
}
For the second case, call delete at the end of the function.
Hope this solves your issue of when to call the delete in your code.
However, you can avoid calling both new and delete in your case by replacing:
wirelessNetwork *g = new wirelessNetwork(10, i);
with
wirelessNetwork g(10, i);
And for accessing the member variables use g. instead of g->.
For example: g->topologyControl(); should be g.topologyControl();
Hope this answer helps.
The best answer is you shouldn't be using pointers or the new operator. As others suggested, just construct the object directly in the scope where it is needed, so it will be destroyed automatically when it goes out of scope.
A very common (but I think very poor) answer to this question, is to delete the object immediately before the pointer goes out of scope and/or put all your delete operations at the same nesting level as the corresponding new operations. As in this case, when that approach is practical, you almost always didn't need the pointer or the new at all. When it is not practical for the lifetime of the object to match the scope in which it is created, then you really need a pointer and use of the new operator and managing the lifetime of the object is one of the harder aspects of C++ programming. There are no generic answers in those cases. But until you have such a problem, don't create it by pointless use of the new operator.
This question already has an answer here:
C++ parameter passing queries (code examples and outputs included)
(1 answer)
Closed 8 years ago.
First of all, i have no idea how to word the title whilst keeping it descriptive if anybody has a better idea feel free to edit.
My question is as follows; I have been given a set of function definitions and calls to these functions which currently operate using an int* as the variable that is being passed in various ways to these functions.
My task is to without changing the function definitions make the program compile and produce the same output but this time use an int over an int*.
Desired output:
Result
first 43
second 43
third 44
fourth 0
fifth 69
This is the code for the when the variable is an int*
void MyIncrementFirst(int* i) {
(*i)++;
}
void MyIncrementSecond(int i) {
i++;
}
void MyIncrementThird(int & i) {
i++;
}
void MyIncrementFourth(int** i) {
*i = new int(0);
}
void MyIncrementFifth(int*& i) {
i = new int(69);
}
int main(){
int* a = new int(42);
cout << "Result" << endl;
MyIncrementFirst(a);
cout << "first " <<*a << endl;
MyIncrementSecond(*a);
cout << "second " <<*a << endl;
MyIncrementThird(*a);
cout << "third " <<*a << endl;
MyIncrementFourth(&a);
cout << "fourth " <<*a << endl;
MyIncrementFifth(a);
cout << "fifth " <<*a << endl;
return 0;
}
Now here is what i have so far when changing the type of a to an int, not an int*:
Note: The function definitions are the same as above.
int main(){
int a = 42;
cout << "Result" << endl;
MyIncrementFirst(&a);
cout << "first " <<a << endl;
MyIncrementSecond(a);
cout << "second " <<a << endl;
MyIncrementThird(a);
cout << "third " <<a << endl;
/*
MyIncrementFourth(&a);
cout << "fourth " <<a << endl;
MyIncrementFifth(a);
cout << "fifth " <<a << endl;
*/
return 0;
}
Which prints:
Result
first 43
second 43
third 44
Calls to MyIncrementFourth and MyIncrementFith have been commented because i am not sure how to translate this to handle an int rather than an int*. Any attempts i do would just be fluke rather than knowledge.
Can anybody help me identify how to correctly complete the calls to MyIncrementFourth and MyIncrementFith in order to achieve a correct result.
Thanks,
Chris.
void foo(int a) {
...
}
int main() {
int a = 5;
foo(a);
return 0;
}
While with * it would be like this
void foo(int* a) {
...
}
int main() {
int a = 5;
foo(&a);
return 0;
}
However, this reminds of C.
You could use the & operator, instead of the *, like this:
void foo(int& a) {
...
}
int main() {
int a = 5;
foo(a);
return 0;
}
I assume you know what passing by value and by reference means. If you want a refresh, take a look in my example here.
[EDIT]
Also note that the code in the first block of yours is not OK, since you call new twice, but you never call delete.
Also, about what you are asking, you cannot do it without using an extra pointer. In other words, it can not be done by only having int a in the play.
Example:
int* a_pointer = &a;
MyIncrementFourth(&a_pointer);
cout << "fourth " << a << ", but a_pointer points to " << *a_pointer << endl;
Why the value of a did not change, despite the fact that we set the a_pointer to be equal with the address of a.
Because inside your function, you are calling new and as you know, it will return a pointer to the new allocated memory.
As a result, a_pointer is assigned a new value. Which value? The address of the new allocated memory.
When you use
int a = 42;
instead of
int* a = new int(42);
fourth and fifth function can't be used. The MyIncrementFourth and MyIncrementFifth (counterintuitive names, by the way) pretend to replace the pointer you allocated in the main with another pointer to another area, allocated inside the functions (and there will be a memory leak since you no longer will be able to delete the original a…). But if you stick to int a = 42 instead of int* a = new int(42), your variable is not a pointer, thus those functions have no pointer they can replace.
You can use:
int* ap = &a;
MyIncrementFourth(&ap);
MyIncrementFifth(ap);
// These calls change what ap points to.
// It does not change the value a.
You can also use:
int* ap = NULL;
MyIncrementFourth(&ap);
MyIncrementFifth(ap);
// These calls change what ap points to.
int* ptr;
MyIncrementFourth(&ptr);
a = *ptr;
delete ptr;
std::cout << "fourth " << a << std::endl;
MyIncrementFifth(ptr);
a = *ptr;
delete ptr;
std::cout << "fifth " << a << std::endl;
I am tasked with two programs and this is the second one. The first program involved no calculation() function and to time the program when it started and finished. My computer will display anything from .523 seconds to .601 seconds.
The second task was to create an inline function for the calculation and I believe that I have done it wrong because it is not faster. I am not sure if I made the calculation function right because it includes display information, or if the inline function should focus only on the multiplication. Either way pulling the arrays out of main and into a function is not faster.
Is the compiler just ignoring it?
#include <ctime>
#include <iostream>
using namespace std;
inline int calculation(){
int i;
double result[10000];
double user[10000];
for(i=0; i<10000; i++){
user[i]=i+100;
}
double second[10000];
for(i=0; i<10000; i++){
second[i]=10099-i;
}
for (i = 0; i < 10000; i++){
result[i] = user[i] * second[i];
}
for (i = 0; i < 10000; i++){
cout << user[i] << " * " << second[i] << " = " << result[i] << '\n';
}
}
int main() {
time_t t1 = time(0); // get time now
struct tm * now = localtime( & t1 );
cout << "The time now is: ";
cout << now->tm_hour << ":" << now->tm_min << ":" << now->tm_sec << endl;
clock_t t; // get ticks
t = clock();
cout << " Also calculating ticks...\n"<<endl;
calculation(); // inline function
time_t t2 = time(0); // get time now
struct tm * now2 = localtime( & t2 );
cout << "The time now is: ";
cout << now2->tm_hour << ":" << now2->tm_min << ":" << now2->tm_sec << endl;
time_t t3= t2-t1;
cout << "This took me "<< t3 << " second(s)" << endl; // ticks
t = clock() - t;
float p;
p = (float)t/CLOCKS_PER_SEC;
cout << "Or more accuratley, this took " << t << " clicks"
<< " or " << p << " seconds"<<endl;
}
Is the compiler just ignoring it?
Most probably, yes. It could be doing that for two reasons:
You're compiling in debug mode. In debug mode all inline keywords are ignored to facilitate debugging.
It's ignoring it because the function is far too long for an inline function, and uses far too much stack space to safely inline, and is only invoked once. The inline keyword is a compiler HINT, not a mandatory requirement. It's the programmer's way of recommending the compiler to inline the function, just like a compiler in release mode will frequently inline functions on its own to increase performance. If it only sees negative value it won't comply.
Also, given the single invocation, it's highly unlikely that you'll even see differences no matter if it works or not. A single native function call is much easier on the CPU than a single task switch at the OS level.
You should disable optimization to verify if what you do has any effect, because there are good chances that the compiler is already inlining the function by itself.
Also, if you want to know exactly what your code does, you should compile with the -s flag in g++, and look at the assembly generated by the compiler for your program. This will remove all uncertainty about what the compiler is doing to your program.
I would not make the function inlined and define arrays as static. For example
int calculation(){
int i;
static double result[10000];
static double user[10000];
for(i=0; i<10000; i++){
user[i]=i+100;
}
static double second[10000];
for(i=0; i<10000; i++){
second[i]=10099-i;
}
for (i = 0; i < 10000; i++){
result[i] = user[i] * second[i];
}
for (i = 0; i < 10000; i++){
cout << user[i] << " * " << second[i] << " = " << result[i] << '\n';
}
}