Simple Address Book using dynamic array - c++

I am working on my school project related to "keeping contacts of customers" in C++.
I already finished my project using std::vector to store contact information for every added person. But now i have to write the same thing using DYNAMIC ARRAY.
Does anybody have any idea or sample code how to declare dynamic array with ability to change its dimension according to how many contacts are added by user ?
I need following:
* Declaration of dynamic array with undefined number of persons and with 6 contacts per each.
* Add a new contact.
* List all contacts in array.
I finished my project using vectors without any problems, but right now i am lost. I studied a lot of articles about working with dynamic arrays in c++ but with no progress. I was searching all around the internet for a sample piece of code that does what i need but can't find anything.

Although this is not exactly the same as your project, this was mine from a few days ago and we had to use a 2d dynamic array using the "new" and "delete" method for strings of names. Remember that any time you use "new" you need to have a "delete" otherwise you will get memory leaks. I hope this helps.
#include <iostream>
using namespace std;
#include <memory.h>
#include <string.h>
#include "ReadString.h"
#include "sort.h"
void main ()
{
bool contMain=true;
const long numNames=20;
long nameAc=0;
char ** ppNames;
ppNames=new char* [numNames];
char test;
while(contMain && nameAc<numNames)
{
ppNames[nameAc]=ReadString();
test=ppNames[nameAc][0];
if(test=='\0')
{
contMain=false;
}
nameAc++;
}
cout<<"Your names unsorted are:"<<endl;
print(ppNames, nameAc);
ppNames=sort(ppNames, nameAc);
cout<<"Your names, sorted, are:"<<endl;
print(ppNames, nameAc);
// deallocation... this will delete pNames and pTemp from the ReadString function
// as well as ppNames in main because they are all using the same pointers.
for(int i=0; i<nameAc; i++)
{
delete ppNames [i];
}
delete[] ppNames;
}
And here is the ReadString function.
#include <iostream>
#include <memory.h>
#include "ReadString.h"
using namespace std;
char * ReadString()
{
long aSize=10;
long numChars (0);
char * pNames;
char * pTemp;
char c;
pNames=new char [aSize+1];
while((c = cin.get()) != '\n')
{
if(numChars >= aSize)
{
aSize += numChars;
pTemp = new char[aSize + 1];
memcpy(pTemp, pNames, numChars);
delete[] pNames;
pNames = pTemp;
cout << "Array size increased to " << aSize << endl;
}
pNames[numChars++] = c;
}
pNames[numChars] = '\0'; //end of string
return pNames;

one thing you can easily use for this are linked lists. Your data structure has a pointer to the next list element.
struct ListElement
{
CustomerData cutomer;
ListElement *next;
}
You can add infrastructure for adding removing, finding, print-all etc. using such a datastructure as basis.
Another way is doing it really dynamic:
Example adding one item:
malloc memory for as many items as you already have + 1
copy the data from the old to the new memory
add the new item at the with +1 allocated space
You'll need infrastructure for adding at the beginning, at the end, delete one in the middle etc. going with this scheme. Allocate as much memory as you need after the change, copy the old data, insert/remove one item.
Good luck with your project!

The best that I can so is to suggest links to articles. It sounds like your instructor wants you to write the same program in "the hard way" using a more primitive set of tools. Since std::vector is essentially a dynamic array, I have to assume that he wants you to rewrite the project where you have to manually manage the memory. Here are some starting points. Remember, that google is your friend!
C++ FAQ Lite
Dynamic Memory Cplusplus.com
LMGTFY

Related

Deleting an array element declared in struct c++

I want to delete the array elements declared under student struct. I have only included parts of the code to reduce confusion.Please find the code below for the two relevant cases:
#include <iostream>
#include <string>
#include <conio.h>
using namespace std;
struct student
{
char name[20];
int id;
};
struct teacher
{
char name[20];
int id;
};
int main()
{
case 1:
cout<<"\t\t\t*********enter record**********"<<endl;
student st[2];
for(int count=0; count<2;count++)
{
cout<<"\t\t\t\tenter student "<<count<<" name"<<endl;
cin>>st[count].name;
cout<<"\t\t\t\tenter student "<<count<<" id"<<endl;
cin>>st[count].id;
}
break;
case 5:
cout<<"\t\t\t*********delete record********"<<endl;
for(int count=0;count<10;count++)
{
delete st[count].name;
}
break;
}
As seen in case 5 I am trying to delete the elements within the array using delete st[count].name;
I want to delete the elements of name and id in the delete case. However using delete st[count].name gives me a [Warning] Deleting array . And when I run the program it gives me a Program Recieved a signal SIGTRAP, trace/breakpoint trap. I am a beginner in c++ please help how I can delete the elements stored in these array. Thanks
There are 2 main problems in your code.
cin>>st[count].name
You're filling the array with user input, but the array can only hold 20 elements (and the last one must be a null terminator), if user inputs text with more then 19 elements, your program will result in undefined behavior.
Later, you're using
delete st[count].name
You're using delete on an array that is allocated on the stack, which is undefined behavior again, you would only need to use delete if you alocate an object using operator new, also you should use delete[] instead of delete for arrays.
The easiest fix to your program is changing char name[20] to std::string, std::string will resize itself to adapt to the text that it's holding dynamicly, while also taking care of clearning memory after itself, so you don't have to worry about that, later on it also has many useful methods that you may find useful, you can read more about std::string.
https://en.cppreference.com/w/cpp/string/basic_string

Concatenation with arrays in C++?

#include <iostream>
using namespace std;
void mystrcat(char destination[], const char source[]){
int counter = 0;
while(source[counter] != '/0'){
destination += source[counter];
counter++;
}
destination += '/0';
}
int main(){
}
For my code, when I try to concatenate with the function mystrcat, my school's test bed says that there was a segmentation error. The purpose of my function is to concatenate while removing the NULL from the end of destination and adding it to the end of source. Is there a segmentation error because I am not removing NULL? If so, how do I access the last element of the array? The number of elements is unknown so I don't know if I can use pop_back. Thank you.
Edit:
#include <iostream>
using namespace std;
void mystrcat(char destination[], const char source[]){
int counter = 0;
int counter2 = 0;
while(destination[counter2] != '/0'){
counter2++;
}
while(source[counter] != '/0'){
destination[counter2 - 1] = source[counter];
counter++;
}
destination[counter] = '/0';
}
int main(){
}
is my edited code but now the testbed says that it is taking too long and crashes.
Arrays in C++ have an interesting property where they can easily decay to pointers.
destination += source[counter]; does not append source[counter] to the end of destination.
Instead, destination has decayed to a pointer and this operation is doing pointer arithmatic on destination.
Instead, you want to do destination[destinationLocation] = source[counter]; to actually set the character in destination.
Don't forget to set destination[end] = '\0'; at the end to null terminate the destination array.
One final thing to watch out for is that C++ will not make sure that your arrays are properly sized. If destination is not of the proper size, the code will fail at run time with a segmentation fault.
For future reference, you might want to look into using C++'s std::vector class. std::vector is a variable sized array-like container which automatically keeps track of its size and memory usage. Using pure arrays in C++ is sometimes difficult and error prone (as you have just seen), so std::vector can make things easier.
Static arrays are a fixed sized in C++. That means you can't extend or shrink them at all under any circumstance.
There are three main alternatives to achieve what you're trying to do. From your code, it looks like the best one would be to use the std::string class (since you're using chars). It contains all the code to manage and concatenate the data very easily.
If you absolutely need an array, then std::vector would be the next best choice. It allows push and pop operations etc., and will automatically resize the underlying dynamic array as needed.
Finally, you could use a dynamic array directly. You would create and destroy it using new [] and delete []. When you need to extend the array, you need to create a new one with the new size, copy the old data over, and destroy the old one. It's a lot of unnecessary extra work though, so the other two options are much better.

How do I go about editing the variables in a struct array?

I've Googled, asked my classmates, and finally asked my professor about this particular problem, but I haven't achieved a solution yet. I'm hoping someone here can help me out.
Basically, I need to make an array of structs that will contain 4 pieces of information per struct: country name, country population, country area, and country density. This information will be written to the structs in the array from a .txt document. This info will then be written onto the console from said array.
Unfortunately, in attempting to write anything to the structs in the array, I get 2 errors. "Cannot convert from 'const char[8]' to 'char [30]'" and "no operator '[]' matches these operands, operand types are: CountryStats [int]". These errors both refer to the line:
countries[0].countryName = "A";
Keep in mind that I have only started to use structs and this is the first time I've used them in an array. Also, I must use an array, as opposed to a vector.
Here's my code:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
struct CountryStats;
void initArray(CountryStats *countries);
const int MAXRECORDS = 100;
const int MAXNAMELENGTH = 30;
struct CountryStats
{
char countryName[MAXNAMELENGTH];
int population;
int area;
double density;
};
// All code beneath this line has been giving me trouble. I need to easily edit the
// struct variables and then read them.
int main(void)
{
CountryStats countries[MAXRECORDS];
initArray(*countries);
}
void initArray(CountryStats countries)
{
countries[0].countryName = "A";
}
As of now I am just attempting to figure out how to write information to a struct within the array and then read the information off of it onto the console. Everything else should fall into place after I find the solution to this.
Oh, and one final note: I have not quite learned the function of pointers (*) yet. I am still relatively new to C++ as my past programming education has been primarily in Java. Any and all inclusions of pointers in this code have been influenced by my classmates and professor in the pursuit of solving this problem.
Thanks in advance!
Two problems
void initArray(CountryStats countries)
must be:
void initArray(CountryStats *countries)
And you must use strcpy to copy c style string. (but i suggest to use c++ string instead of char[])
strcpy(countries[0].countryName,"A");
But I say again, use c++ features like vector<> and string.
You are not defining a definition for:
void initArray(CountryStats *countries);
but for:
void initArray(CountryStats countries);
in which countries is not an array. Since no operator[] is defined for CountryStats, the expression countries[0] fails to compile.
Since you cannot use std::vector (for some weird reasons), I'd suggest you to use an std::array:
template<std::size_t N>
void initArray(std::array<CountryStats, N>& ref) {
for (std::size_t i = 0; i < N; i++)
// initialize ref[i]
}
Of course, if you feel masochist, you can also use a C-style array:
void initArray(CountryStats* arr, int size) {
for (int i = 0; i < size; i++)
// initialize arr[i]
}
But you'll, probably, need to provide the dimension of the array as a second parameter.

c++ dynamic stuct pointer to char array

I'm having trouble dynamically assigning memory to a char array inside a pointer to a struct.
This is a homework assignment that has to use this struct outline:
struct Student
{
char *namePtr;
unsigned int score;
};
this is the part im having trouble with though
/***************************
* takes value from temporary value and puts into dynamic allocated Student array
***************************/
bool updateStructPtr(Student **info, unsigned int index, char *name, unsigned int score)
{
try
{
info[index]->namePtr = new char [strlen(name)+1];
if(DEBUG) cout << "size for dynamic char: " << strlen(name)+1 << endl << endl;
//copy char array into new array
strcpy(info[index]->namePtr, name);
info[index]->score = score;
}
catch (bad_alloc & param)
{
info[index]->namePtr = NULL;
return false;
}
return true;
}
my prof said:
A glance at your code reveals that you do not seem to be dynamically allocating memory for the Student structure as specified in the first sentence of step 3-2 of the algorithm I provided you.
3-2. Dynamically allocate memory for a Student structure. Place the address of this Student structure in the array of structure pointers. You will also need to dynamically allocate just enough memory to store the name. Do not store the quote characters. Populate the fields of the Student structure with the two items from Step 3-1.
The pointers in the pointer array point to random locations in memory and you are trying to use these random addresses. That could certainly explain why the program crashes. Actually there are many ways to crash this program and all steps must be followed carefully to avoid this.
but i have no idea how to fix this or where to begin.
SO isn't really intended for help with your homework.
That being said, the instructions from your teacher are quite elaborate and correct. You'll have to use new Student and new Student[] at one point or another to actually update the Student ** info that is passed to you in order to add that new Student struct you're supposed to add.
I'm guessing Student instances are not allocated before the function is called. You would have to allocate a new instance of Student via new Student and store it into info at index.
info[index] = new Student;

how do you add value in runtime to structural arrays (in c++)

This question was migrated 12 years ago.
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
int main (){
int a,b;
b = 0;
cout<<" this is a family profiling program to test my knowledge of structural arrays. ";
cin>> a;
struct p {
char name[20];
int age;
char hobby[40];
char favcolor[15];
};
p family[2];
**cin.getline(family.name[0]);**
cout<<"enter the name of family member"<<b+1;
I am trying to use this code to create a family profiling program, i know how to add value to an array or structural array during compiler time but not to use cin or cin.getline to add a value to to a specific value in a specific structure of an array.
please respond with a simple answer; Im still new to programming.(my attempt is bolded
If you insist on using an array, the easiest way to do this (add elements to a fixed-size array) would be to copy everything to a NEW array, including the new item.
A much better way would be to use a dynamic structure, such as a linked list. The standard template library and the boost library have many ways to help you here, but you could also easily implement a simple linked list on your own (or find code for it).
As Mike Chess said, this is probably best asked on http://www.stackoverflow.com
(also, to get your code formatted nicely, edit your post, select the code section, and click the button with the ones and zeros icon just above the text area)
Firstly, you'll find it much easier to write reliable code if you use std::string instead of character arrays. You were nearly on the right track though: instead of family.name[0] try family[0].name, then getline will work with std::string as below...
struct p
{
std::string name;
// other stuff...
};
if (getline(std::cin, family[0].name))
{
// it worked!
...
}
The "high performance" and old school option is to use realloc like this.
p * family = malloc(sizeof(p)*2);
family = realloc(family, sizeof(p)*13);
Of course this doesn't invoke constructors, and is not really acceptable in C++ generally. So your best option is.
#include <list>
using namespace std;
...
list<p> family;
p blah;
family.push_back(blah);
That's a linked list so it's perfect for datasets of unknown length. Same code can be used for an STL vector, which if you predict the size of your input in advance well enough will give you a performance boost.