2

I have a program that should create a sorted linked list by name. However, after running it, the output gives me an error:

Undefined symbols for architecture x86_64:

"StudentList::insertNode(Student)", referenced from:
      buildList(StudentList&) in main-acc0ea.o
  "StudentList::StudentList()", referenced from:
      _main in main-acc0ea.o
  "StudentList::~StudentList()", referenced from:
      _main in main-acc0ea.o
  "StudentList::displayList(double) const", referenced from:
      _main in main-acc0ea.o
  "StudentList::displayList(double, double) const", referenced from:
      _main in main-acc0ea.o
  "StudentList::displayList() const", referenced from:
      _main in main-acc0ea.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

My code:

File Main.cpp

#include <iostream>
#include "StudentList.h"

using namespace std;

void buildList(StudentList &);

int main()
{
   // Define a StudentList object
   StudentList list;
   buildList(list); // Insert data into the list
   list.displayList();
   double gpa;
   cout << "Enter a gpa: ";
   cin >> gpa;
   list.displayList(gpa);
   double from, to;
   cout << "Enter a gpa range: ";
   cin >> from >> to;
   list.displayList(from, to);
   system("pause");
   return 0;
}

void buildList(StudentList &list)
{
   // Define and initialize an array of Student objects
   Student s[10] =
       { { 2.3, "Tom" }, { 2.5, "John" }, { 3.1, "Paul" }, { 3.9, "Linda" }, { 3.6, "Bob" }, { 2.7, "Ann" }, { 4.0, "Mary" },
       { 3.2, "Andy" }, { 0, "#" } };

   //Insert data from array into the linked list
   for (int i = 0; s[i].name != "#"; i++)
   {
       list.insertNode(s[i]);
   }
}

File StudentList.h

#ifndef STUDENTLIST_H
#define STUDENTLIST_H

#include<string>

struct Student
{
   double gpa;
   std::string name;
};

class StudentList
{
private:
   // Declare a structure for the list
   struct ListNode
   {
       Student stu; // The value in this node
       ListNode *next; // To point to the next node
   };
   ListNode *head; // List head pointer
   int count; // To keep track of the number of nodes in the list

public:
   StudentList(); // Constructor
   ~StudentList(); // Destructor

                   // Linked list operations
   int getCount() const { return count; }
   void insertNode(Student);
   void displayList() const;
   void displayList(double) const;
   void displayList(double,double) const;
   /* Write your code here */
};
#endif

File StudentList.cpp

#include <iostream> // For cout and NULL
#include "StudentList.h"

using namespace std;

//**************************************************
// Constructor
// This function allocates and initializes a sentinel node
// A sentinel (or dummy) node is an extra node added before the first data record.
// This convention simplifies and accelerates some list-manipulation algorithms,
// by making sure that all links can be safely dereferenced and that every list
// (even one that contains no data elements) always has a "first" node.
//**************************************************
StudentList::StudentList()
{
   head = new ListNode; // head points to the sentinel node
   head->stu.gpa = -1;
   head->stu.name = "";
   head->next = NULL;
   count = 0;
}

//**************************************************
// displayList shows the value
// stored in each node of the linked list
// pointed to by head.
//**************************************************
void StudentList::displayList() const
{
   ListNode *pCur; // To move through the list
                   // Position pCur: skip the head of the list.
   pCur = head->next;
   // While pCur points to a node, traverse the list.
   cout << endl;
   while (pCur)
   {
       // Display the value in this node.
       cout << pCur->stu.gpa << " " << pCur->stu.name << endl;
       // Move to the next node.
       pCur = pCur->next;
   }
   cout << endl;
}

//**************************************************
// The insertNode function inserts a node with
// stu copied to its value member.
//**************************************************
void StudentList::insertNode(Student dataIn)
{
   ListNode *newNode; // A new node
   ListNode *pCur; // To traverse the list
   ListNode *pPre; // The previous node
                   // Allocate a new node and store num there.
   newNode = new ListNode;
   newNode->stu = dataIn;
   // Initialize pointers
   pPre = head;
   pCur = head->next;
   // Find location: skip all nodes whose gpa is less than dataIn's gpa
   while (pCur != NULL && pCur->stu.name < dataIn.name)
   {
       pPre = pCur;
       pCur = pCur->next;
   }
   // Insert the new node between pPre and pCur
   pPre->next = newNode;
   newNode->next = pCur;
   // Update the counter
   count++;
}

//**************************************************
// Destructor *
// This function deletes every node in the list. *
//**************************************************
StudentList::~StudentList()
{
}

void StudentList::displayList(double aboveGPA) const
{
   ListNode *pCur; // To move through the list
                   // Position pCur: skip the head of the list.
   pCur = head->next;
   // While pCur points to a node, traverse the list.
   cout << endl;
   while (pCur)
   {
       if (pCur->stu.gpa >= aboveGPA)
       {
           // Display the value in this node.
           cout << pCur->stu.gpa << " " << pCur->stu.name << endl;
       }
       // Move to the next node.
       pCur = pCur->next;
   }
   cout << endl;
}

void StudentList::displayList(double gpa1, double gpa2) const
{
   ListNode *pCur; // To move through the list
                   // Position pCur: skip the head of the list.
   double upperLimit, loweLimit;
   if (gpa1 > gpa2)
   {
       upperLimit = gpa1;
       loweLimit = gpa2;
   }
   else
   {
       upperLimit = gpa2;
       loweLimit = gpa1;
   }
   pCur = head->next;
   // While pCur points to a node, traverse the list.
   cout << endl;
   while (pCur)
   {
       if (pCur->stu.gpa >= loweLimit && pCur->stu.gpa<=upperLimit)
       {
           // Display the value in this node.
           cout << pCur->stu.gpa << " " << pCur->stu.name << endl;
       }
       // Move to the next node.
       pCur = pCur->next;
   }
   cout << endl;
}

I don't know if my code is wrong or if it's this problem:

Visual Studio Code clang error: linker command failed with exit code 1 on Mac

I tried adding "${fileDirname}/*.cpp" in my task JSON file, but it's still giving me the same error. Is there another solution for this error?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
drewster
  • 83
  • 1
  • 8

1 Answers1

1

The linker does not find the symbols it complains about. Probably because it doesn't look into the StudentList object file.

Try to find out how it is invoked, and check whether the StudentList object file is given to it. If not, find out why.

xtofl
  • 40,723
  • 12
  • 105
  • 192