1

I am working on an assignment which to create a program that can read a polynomial from a text file using linked list. Which when i tried to return the starting pointer of the linked list "poly_pointer" from the read_poly function things being weird.

The expected output should be -12

But what i got is -10

And if i add one single line of code right before return in read_poly

cout << curr_ptr->coef;

the output would suddenly turns to 2-12 May anyone provide some explanation on why and how to fix this problem?

Polynomial.h

#ifndef _POLYNOMIAL_H_
#define _POLYNOMIAL_H_

using namespace std;

typedef struct poly_node *poly_pointer;

typedef struct poly_node {
  int coef;
  int expon;
  poly_pointer link;
};

poly_pointer addNode(int coef, int expon);

#endif

Polynomial.cpp

#include <iostream>
#include <fstream>
#include <string>
#include "Polynomial.h"
using namespace std;

poly_pointer addNode(int coef, int expon)
{
    poly_node a;
    poly_pointer ptr = &a;
    a.coef = coef;
    a.expon = expon;
    return ptr;
}

poly_pointer read_poly(const char* fileName)
{
    poly_pointer start_ptr, curr_ptr;
    start_ptr = curr_ptr = addNode(-1, 6);
    curr_ptr = curr_ptr->link = addNode(2, 3);
    return start_ptr;
}

main.cpp

#include <iostream>
#include "Polynomial.h"
using namespace std;

int main(void)
{
    poly_pointer a, b, d, e, f;
    a = read_poly("input1.txt");
    cout << a->coef;
    cout << a->link->coef;

    cout << "\n-eop-";
    cin.get();
    return 0;
}
hemantai
  • 15
  • 4
  • 3
    `_POLYNOMIAL_H_` violates the rules of reserved identifiers: http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier. You also should at least avoid `using namespace std;` in the global scope of the header file at all costs. – chris Sep 28 '12 at 01:37
  • 2
    As for your problem, http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope – chris Sep 28 '12 at 01:38

3 Answers3

2

addNode is returning a pointer to a locally allocated poly_node.

The following is sloppy allocation of memory, but will work.

  poly_pointer a = new poly_pointer();
  a->coef = coef;
  a->expon = expon;
  return a;
mmodahl
  • 176
  • 4
  • thx, but i got an error like this 1>Polynomial.cpp(9): error C2440: 'initializing' : cannot convert from 'poly_pointer *' to 'poly_pointer' – hemantai Sep 28 '12 at 01:53
  • Sorry, I mixed the notation there. Use new poly_node. – mmodahl Sep 28 '12 at 01:53
  • On the notation, having a typedef pointer type makes certain aspects more confusing, at least to me. You might stick with only using poly_node* types in code. – mmodahl Sep 28 '12 at 01:55
  • The other comments aren't incorrect though. This implementation could leak if the pointer isn't later deleted. This works, but keep learning about pointers. – mmodahl Sep 28 '12 at 01:56
  • umm... what actually is leak in the sense of pointer? And what should i do to delete the pointer? Is it i should be deleting the pointer and the end of the main()? – hemantai Sep 28 '12 at 02:01
1
poly_node a;
poly_pointer ptr = &a;
a.coef = coef;
a.expon = expon;
return ptr;

Bad! You returned a pointer to a local variable. Using that pointer after the function exits triggers undefined behaviour. Use malloc or new instead if you want to return a value which lives on past the function's lifetime.

nneonneo
  • 171,345
  • 36
  • 312
  • 383
  • 1
    The code in question and the answer about malloc both look C-Style code than C++. – Jagannath Sep 28 '12 at 01:44
  • thx for the answer, i think i understand what you are talking about. But what should i actually do with my code in order to make it work? Sorry i am kind of new to the pointer stuff. – hemantai Sep 28 '12 at 01:48
  • @hemantai, A smart pointer won't leak on you and you can pass it around with ease. C++03 just has `auto_ptr`, which got replaced with three different ones in C++11. Easier would probably be to not use a pointer at all and let NRVO do its thing. – chris Sep 28 '12 at 01:52
0

Just return it by value. Fine for the struct you have.

poly_node addNode(int coef, int expon)
{
    poly_node a;
    a.coef = coef;
    a.expon = expon;
    return a;
}

If the type is large, then allocate memory on heap and return the pointer. The ownership of releasing the memory is on the caller of the method.

poly_pointer addNode(int coef, int expon)
{
    poly_pointer a = new poly_node();
    a->coef = coef;
    a->expon = expon;
    return a;
}

If you have compiler that supports std::unique_ptr or std::shared_pointer, then use them instead of raw pointers.

Jagannath
  • 3,995
  • 26
  • 30