I have written the following code in C++, however found out that I have to convert it in C. I am not C or even C++ programmer, please help.
Can someone help me change this method to C directives, specifically vector implementation, following will not compile I have removed complexity to keep it simple. Thanks in anticipation.
__declspec(dllexport) std::vector<MY_STRUCT> WINAPI ABC(char *strVal)
{
MY_STRUCT f;
std::vector<MY_STRUCT> list = std::vector<MY_STRUCT>();
while (*dddd)
{ /*do the following for every feature in license file*/
f.attrib_num = fi.attrib_num;
f.attrib_lic = fi.attrib_lic;
list.push_back(f);
} /* end while(conf) */
dddd++;
printf("\n");
} /* end while (*dddd) */
return flist;
}
Here is implementation (also usage) of dynamic array of structs in C. You can adapt it to your structure; I used to post it on code review before
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
int ID;
char * name;
} Student;
// array of structs
typedef struct
{
Student *array;
size_t used;
size_t size;
} Array;
void initArray(Array *a, size_t initialSize)
{
int i = 0;
// Allocate initial space
a->array = malloc(initialSize * sizeof(Student));
a->used = 0; // no elements used
a->size = initialSize; // available nr of elements
// Initialize all values of the array to 0
for(i = 0; i<initialSize; i++)
{
memset(&a->array[i],0,sizeof(Student));
}
}
// Add element to array
void addElement(Array *a, Student element)
{
int i = 0;
if (a->used == a->size)
{
a->size *= 2;
a->array = realloc(a->array, a->size * sizeof(Student));
// Initialize the last/new elements of the reallocated array
for(i = a->used; i<a->size; i++)
{
memset(&a->array[i],0,sizeof(Student));
}
}
// Copy name
a->array[a->used].name = (char*)malloc(strlen(element.name) + 1);
strcpy(a->array[a->used].name, element.name);
// Copy ID
a->array[a->used].ID=element.ID;
a->used++;
}
void freeArray(Array *a)
{
int i = 0;
// Free all name variables of each array element first
for(i=0; i<a->used; i++)
{
free(a->array[i].name);
a->array[i].name=NULL;
}
// Now free the array
free(a->array);
a->array = NULL;
a->used = 0;
a->size = 0;
}
int main(int argc, const char * argv[])
{
Array a;
Student x,y,z;
x.ID = 20;
x.name=malloc(strlen("stud1") + 1);
strcpy(x.name,"stud1");
y.ID = 30;
y.name=malloc(strlen("student2") + 1);
strcpy(y.name,"student2");
z.ID = 40;
z.name=malloc(strlen("student3") + 1);
strcpy(z.name,"student3");
// Init array, don't forget
initArray(&a, 5);
// Add elements
addElement(&a, x);
addElement(&a, y);
addElement(&a, z);
// Print elements
printf("%d\n", a.array[0].ID);
printf("%s\n", a.array[0].name);
printf("%d\n", a.array[1].ID);
printf("%s\n", a.array[1].name);
printf("%d\n", a.array[2].ID);
printf("%s\n", a.array[2].name);
// Free array
// don't forget
freeArray(&a);
free(x.name);
free(y.name);
free(z.name);
return 0;
}
Related
I'm attempting to implement an intvector in C++ and am getting a "Segmentation fault: 11" error. I understand this has something to do with memory management, and considering how new I am to C++ it could definitely be a pretty minor mistake. I debugged the code with valgrind and was given messages such as the following:
Use of uninitialized value of size 8, Invalid read of size 4,Conditional jump or move depends on uninitialized value(s).
My best guess is it has something to do with how I'm implementing the arrays. I originally had the arrays stored on the heap but changed it to the stack and still got the same error. I've already implemented an intvector in java, so I was attempting to use similar logic here, which perhaps is part of the issue.
#include <iostream>
#include "IntVector.h"
#include <cmath>
using namespace std;
int num_elements = 0;
int array_size = 0;
int expansion_factor;
void IntVector::expandArray(){
int tempArr[array_size*2];
for(int i =0;i<array_size;i++){
tempArr[i] = array[i];
}
array = tempArr;
array_size = array_size * 2;
}
void IntVector::add(int val){
int tempArr[array_size];
if(array_size == num_elements){
expandArray();
array[num_elements] = val;
}
else{
for(int i = 0;i<array_size;i++){
tempArr[i] = array[i];
}
tempArr[num_elements] = val;
array = tempArr;
}
num_elements++;
}
void IntVector::remove(int index){
}
int IntVector::get(int index) const{
return index;
}
void IntVector::removeLast(){
}
void IntVector::set(int index, int val){
}
std::string IntVector::toString()const {
return "";
}
IntVector::IntVector(int initial_size){
int* array = new int[initial_size];
}
IntVector:: ~IntVector(){
delete[] array;
}
int main(){
IntVector v(0);
v.add(5);
}
#ifndef INTVECTOR_H_
#define INTVECTOR_H_
using std::cout;
class IntVector {
private:
int* array;
int num_elements;
int array_size;
int expansion_factor;
void expandArray();
public:
void add(int val);
void remove(int index);
int get(int index) const;
void removeLast();
void set(int index, int val);
std::string toString() const;
IntVector(int initial_size);
~IntVector();
};
#endif
As mention in the comments, there are definitely some holes in your understanding of C++. Really when dealing with header files you should have a main.cpp, someotherfile.h, someotherfile.cpp. That just best practices to avoid redefinition errors.
There was quite a bit wrong with the way you accessed the private variable. If a class has a private( or even public) variable you don't have to redeclare it each time you want to change its value.
There were one or two major flaws with the way you expanded the vector. If the vector size is initialized to 0 then 0*2 is still 0 so you never actually increased the size. Secondly, when you set the original array = to the new array the new array was just a local array. This means that the memory wasn't actually allocated permanently, once the function ended the temparr was destroyed.
I know this was probably a lot but if you have any question feel free to ask.
main.cpp
#include "IntVector.h"
int main()
{
IntVector v;
IntVector x(10);
v.push(5);
v.push(5);
v.push(5);
v.push(5);
v.push(5);
v.print();
cout << endl;
x.push(5);
x.push(5);
x.push(5);
x.push(5);
x.push(5);
x.print();
return 0;
}
IntVector.h
#include <string>
#include <iostream>
using namespace std;
class IntVector {
private:
int *array;
int num_elements;
int array_size;
//int expansion_factor =; you would only need this if you plan on more than double the vector size
void expandArray(); //normally c++ array double in size each time they expand
public:
//Constructors
IntVector(); //this is a contructor for if nothing is called
IntVector(int initial_size);
//setters
void push(int val); //add
void pop(); //removelast
void remove(int index); //remove
void at(int index, int val); //set
//Getters
int at(int index);
//std::string toString(); I'm changing this to print
void print(); //will print the contents to the terminal
//Deconstructor
~IntVector();
};
IntVector.cpp
#include "IntVector.h"
//constructors
IntVector::IntVector() //no arguments given
{
array = new int[0];
num_elements = 0;
array_size = 0;
}
IntVector::IntVector(int initial_size)
{
array = new int[initial_size];
num_elements = 0;
array_size = initial_size;
}
void IntVector::expandArray()
{
int *tempArr;
if(array_size == 0){
array_size = 1;
tempArr = new int[1];
} else {
//make sure to allocate new memory
//you were creating a local array which was destroy after the function was completed
//using new will allow the array to exist outside the function
tempArr = new int[array_size * 2];
}
for (int i = 0; i < array_size; i++)
{
tempArr[i] = array[i];
}
//make sure to delete the old array otherwise there is a memory leak.
//c++ doesn't have a garbage collector
delete[] array;
array = tempArr;
array_size = array_size * 2;
}
void IntVector::push(int val)
{
num_elements++;
//checking if vector needs to increase
if (array_size <= num_elements)
{
expandArray();
array[num_elements-1] = val;
}
else
{
array[num_elements-1] = val;
}
}
void IntVector::remove(int index)
{
//not sure how to implment this becuase each element has to be a number.
}
int IntVector::at(int index)
{
return array[index];
}
void IntVector::pop()
{
num_elements = num_elements-1; //not really removing it from the "vector" but it won't print out again
}
void IntVector::at(int index, int val)
{
array[index] = val;
}
void IntVector::print()
{
for (int i = 0 ; i < num_elements; i++)
{
cout << array[i] << " ";
}
cout << endl;
}
IntVector::~IntVector()
{
delete[] array;
}
output
5 5 5 5 5
5 5 5 5 5
Hopefully, the comments help. I changed the name of the functions to better match the actual vecter class the already exists in C++. I think it's good to pick apart already defined functions like this because you get a better understanding of how they actually work and not just how to use them.
If you got any questions just leave a comment
This is my code:
#include <cstdlib>
#include <ctime>
#include <stdio.h>
#include <vector>
#define ENTITY(A) entity##A
#define ALM(A) alm##A
struct TEntity{
private:
int sumx;
int sumy;
const char * rep;
int m_ix;
int m_iy;
public:
TEntity(int x, int y, int sum_x, int sum_y, const char * txt);
};
TEntity::TEntity(int x, int y, int sum_x, int sum_y, const char * txt) {
m_ix = x;
m_iy = y;
sumx = sum_x;
sumy = sum_y;
rep = txt;
}
class IAlmacenable {
private:
void * element;
public:
IAlmacenable(void * e);
IAlmacenable();
void * getValue();
};
IAlmacenable::IAlmacenable(void *e) {
element = e;
}
IAlmacenable::IAlmacenable() {
element = nullptr;
}
void * IAlmacenable::getValue() {
return element;
}
class TList {
private:
std::vector<IAlmacenable*> elementos;
int position;
public:
TList();
int Size();
int Push(IAlmacenable* psz);
};
TList::TList() {
elementos = std::vector<IAlmacenable*>();
position = 0;
}
int TList::Size() {
return elementos.size();
}
int TList::Push(IAlmacenable* psz) {
int res = 0;
if (elementos.size() >= elementos.max_size()) {
res = -1;
}
else {
elementos.push_back(psz);
}
return res;
}
int main(){
srand(time(NULL));
TList *list = new TList();
//we can put entities in the list and the rest will be filled up to 5
int size = list->Size();
for(int i = size; i<5;i++){
const char c[] = {(rand() % 2 ? 65 + rand() % 25 : 97 + rand() % 25), '\0'};
TEntity ENTITY(i)(rand() % 10, rand() % 10, rand() % 5, rand() % 5, c);
IAlmacenable ALM(i)(&ENTITY(i));
list->Push(&ALM(i));
size++;
}
//do things like printing their value...
delete list;
return 0;
}
I need to create a new variable everytime it run the "TEntity ENTITY(i)" line,
the problem is that it creates the same variable always, I think it is because it creates the variable entityi and therefore it is overwriting on the same variable, besides it seems that the random it generates is always the same number since all entities have the same values in all its parameters. The c variable create a const char * random variable between a-z, A-Z , I don't put the print code because it is unnecessary, so what can I do? Is there any way to dynamically create variables of entities whose values are random?
EDIT
Here is the new code fixed (the macros have been eliminated since they were not necessary and the necessary code has been included to be able to execute it) but there is still the same problem that they are generated with the same parameters (since they are still the same variable):
#include <cstdlib>
#include <ctime>
#include <stdio.h>
#include <vector>
#include <conio.h>
#include <windows.h>
struct TEntity{
private:
int sumx;
int sumy;
const char * rep;
int m_ix;
int m_iy;
public:
TEntity(int x, int y, int sum_x, int sum_y, const char * txt);
void movimiento();
void pinta();
};
TEntity::TEntity(int x, int y, int sum_x, int sum_y, const char * txt) {
m_ix = x;
m_iy = y;
sumx = sum_x;
sumy = sum_y;
rep = txt;
}
void TEntity::movimiento() {
m_ix += sumx;
m_iy += sumy;
}
void TEntity::pinta() {
gotoxy(static_cast<short int>(m_ix), static_cast<short int>(m_iy));
printf("%s", rep);
}
void gotoxy(short int x, short int y)
{
COORD pos = {x, y};
HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(output, pos);
}
void clear()
{
system("cls");
}
class IAlmacenable {
private:
void * element;
public:
IAlmacenable(void * e);
IAlmacenable();
void * getValue();
};
IAlmacenable::IAlmacenable(void *e) {
element = e;
}
IAlmacenable::IAlmacenable() {
element = nullptr;
}
void * IAlmacenable::getValue() {
return element;
}
class TList {
private:
std::vector<IAlmacenable*> elementos;
int position;
public:
TList();
int Size();
int Push(IAlmacenable* psz);
IAlmacenable* First();
IAlmacenable* Next();
};
TList::TList() {
elementos = std::vector<IAlmacenable*>();
position = 0;
}
int TList::Size() {
return elementos.size();
}
int TList::Push(IAlmacenable* psz) {
int res = 0;
if (elementos.size() >= elementos.max_size()) {
res = -1;
}
else {
elementos.push_back(psz);
}
return res;
}
IAlmacenable* TList::First() {
IAlmacenable* res;
if (elementos.empty()) {
res = nullptr;
}
else {
res = elementos.front();
position = 1;
}
return res;
}
IAlmacenable* TList::Next() {
IAlmacenable* res;
if (elementos.empty()) {
res = nullptr;
}
else {
int pos = position;
int size = elementos.size();
if (pos < size) {
res = elementos.at(position);
position++;
}
else {
res = this->First();
}
}
return res;
}
int main(){
srand(time(NULL));
TList *list = new TList();
//we can put entities in the list and the rest will be filled up to 5
int size = list->Size();
for(int i = size; i<5;i++){
const char c[] = {(rand() % 2 ? 65 + rand() % 25 : 97 + rand() % 25), '\0'};
TEntity *entity = new TEntity(rand() % 10, rand() % 10, rand() % 5, rand() % 5, c);
IAlmacenable *alm = new IAlmacenable(entity);
list->Push(alm);
size++;
}
while(true){
clear();
for (int i = 0; i < size; i++) {
reinterpret_cast<TEntity *>(list->Next()->getValue())->pinta();
reinterpret_cast<TEntity *>(list->Next()->getValue())->movimiento();
}
Sleep(2000);
}
delete list;
return 0;
}
There is some confusion here.
Some points:
The macro is not fit-for-purpose, as you already know; you're just creating a variable name entityi each time;
That doesn't matter! The object only exists for the duration of the loop iteration anyway; C++ doesn't let you create multiple objects with the same name at the same time. In fact you can get rid of the entire macro stuff and just call the object entity;
Now that that's out of the way, you're getting repeated results because you're storing a pointer to each iteration of that local variable — on each occasion, that's a dangling pointer to an object that's been destroyed. Don't store dangling pointers!
You can either:
Dynamically allocate the objects that you're adding to the list, or
Store actual objects rather than pointers-to-objects.
Either way, the local-scope name is irrelevant and certainly need not change repeatedly for each loop iteration.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have a application that is suppose to store graphic elements. I am having an issue where I cant access a variable in a structure. Here is what i have so far.
#include <crtdbg.h>
#include <string.h>
#include <stdio.h>
#include "CLib.h"
enum{ RUNNING = 1 };
struct Point
{
int x, y;
};
struct Line
{
Point start;
Point end;
};
struct GraphicElement
{
enum{ SIZE = 256 };
char name[SIZE];
CStash Lines; // a Stash of Lines
};
struct VectorGraphic
{
CStash Elements; // a Stash of GraphicElements
};
void AddGraphicElement(VectorGraphic*);
void ReportVectorGraphic(VectorGraphic*);
void CleanUpVectorGraphic(VectorGraphic*);
VectorGraphic Image;
int main()
{
char response;
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
// it's a Stash of GraphicElements initialize(&(Image.Elements),sizeof(GraphicElement));
while (RUNNING)
{
printf("\nPlease select an option:\n");
printf("1. Add a Graphic Element\n");
printf("2. List the Graphic Elements\n");
printf("q. Quit\n");
printf("CHOICE: ");
fflush(stdin);
scanf("%c", &response);
switch (response)
{
case '1':AddGraphicElement(&Image); break;
case '2':ReportVectorGraphic(&Image); break;
case 'q':CleanUpVectorGraphic(&Image); return 0;
default:printf("Please enter a valid option\n");
}
printf("\n");
}
return 0;
}
void AddGraphicElement(VectorGraphic* pImage){
int i = 0, counter = 0;
int xPointStart = 0, yPointStart = 0;
int xPointEnd = 0, yPointEnd = 0;
char name[50];
int lineNumber = 0;
GraphicElement *pElement = nullptr;
Line *pLine = nullptr;
initialize(&(Image.Elements), sizeof(GraphicElement));
printf("ADDING A Graphic Element\n");
printf("Please enter the name of the new GraphicElement(<256 characters): ");
fflush(stdin);
scanf("\n%[^\n]s", &name);
fflush(stdin);
strcpy(pElement->name,name);
Anytime I try assigning strcpy(pElement->name,name); it tells me access violation.
The two other files im working with that cannot be changed and are from a textbook called Thinking in C++.
//: C04:CLib.cpp {O}
// Implementation of example C-like library
// Declare structure and functions:
#include "CLib.h"
#include <iostream>
#include <cassert>
using namespace std;
// Quantity of elements to add
// when increasing storage:
const int increment = 100;
void initialize(CStash* s, int sz)
{
s->size = sz;
s->quantity = 0;
s->storage = nullptr;
s->next = 0;
}
int add(CStash* s, const void* element)
{
if (s->next >= s->quantity) //Enough space left?
inflate(s, increment);
// Copy element into storage,
// starting at next empty space:
int startBytes = s->next * s->size;
unsigned char* e = (unsigned char*)element;
for (int i = 0; i < s->size; i++)
s->storage[startBytes + i] = e[i];
s->next++;
return(s->next - 1); // Index number
}
void* fetch(CStash* s, int index)
{
// Check index boundaries:
assert(0 <= index);
if (index >= s->next)
return 0; // To indicate the end
// Produce pointer to desired element:
return &(s->storage[index * s->size]);
}
int count(CStash* s)
{
return s->next; // Elements in CStash
}
void inflate(CStash* s, int increase)
{
assert(increase > 0);
int newQuantity = s->quantity + increase;
int newBytes = newQuantity * s->size;
int oldBytes = s->quantity * s->size;
unsigned char* b = new unsigned char[newBytes];
for (int i = 0; i < oldBytes; i++)
b[i] = s->storage[i]; // Copy old to new
delete[](s->storage); // Old storage
s->storage = b; // Point to new memory
s->quantity = newQuantity;
}
void cleanup(CStash* s)
{
if (s->storage != 0)
{
cout << "freeing storage" << endl;
delete[]s->storage;
}
} ///:~
and the .h file...
//: C04:CLib.h
// Header file for a C-like library
// An array-like entity created at runtime
typedef struct CStashTag {
int size; // Size of each space
int quantity; // Number of storage spaces
int next; // Next empty space
unsigned char* storage;// Dynamically allocated array of bytes
} CStash;
void initialize(CStash* s, int size);
void cleanup(CStash* s);
int add(CStash* s, const void* element);
void* fetch(CStash* s, int index);
int count(CStash* s);
void inflate(CStash* s, int increase);
///:~
GraphicElement *pElement = nullptr;
// ...
strcpy(pElement->name,name);
Somewhere between the top line and bottom line above you need to allocate memory for pElement.
pElement = new GraphicElement();
Also, consider using a std::shared_ptr instead of a raw pointer, given you tagged this C++.
While I was trying to create an array in c++ class, there arose a problem while using the constructor. Here is the code:
int stacksize = 100;
int* buffer;
int stackpointer[3]= {-1, -1, -1};
public:
threestack(int stacksize_u)
{
int buffer_u[stacksize_u*3];
this->buffer = buffer_u;
this->stacksize = stacksize_u;
}
threestack()
{
int buffer_u[(this->stacksize)*3];
this->buffer = buffer_u;
}
This actually did not work. When I create the array in the declaration, however, it worked:
int stacksize = 100;
int buffer[300];
int stackpointer[3]= {-1, -1, -1};
Can anybody tell me what is wrong while I was using the constructor?
PSS: Here is the whole class and test program:
class threestack
{
int stacksize = 100;
int* buffer;
int stackpointer[3]= {-1, -1, -1};
public:
threestack(int stacksize_u)
{
int buffer_u[stacksize_u*3];
this->buffer = buffer_u;
this->stacksize = stacksize_u;
}
threestack()
{
int buffer_u[(this->stacksize)*3];
this->buffer = buffer_u;
}
bool push(int stacknum, int value);
bool pop(int stacknum);
int peek(int stacknum);
bool empty(int stacknum);
};
bool threestack::push(int stacknum, int value)
{
if(stackpointer[stacknum-1]+1 >= stacksize)
{
cout<<"Plz do not try to push to a full stack"<<endl;
// printf("stackpointer = %d\n", stackpointer[stacknum-1]);
return 0;
}
else
{
stackpointer[stacknum-1]++;
buffer[stackpointer[stacknum-1]+(stacknum-1)*stacksize] = value;
return 1;
}
}
int threestack::peek(int stacknum)
{
if(stackpointer[stacknum-1] < 0)
{
printf("No element in stack now.\n");
return 0;
}
else
{
printf("stackpointer = %d\n", stackpointer[stacknum-1]);
return buffer[stackpointer[stacknum-1]+(stacknum-1)*stacksize];
}
}
bool threestack::pop(int stacknum)
{
if(stackpointer[stacknum-1] < 0)
{
printf("Plz do not try to pop an empty stack.\n");
return 0;
}
else
{
stackpointer[stacknum-1]--;
}
return 1;
}
bool threestack::empty(int stacknum)
{
if(stackpointer[stacknum-1] < 0)
{
return true;
}
else
{
return false;
}
}
int main(int argc, const char * argv[])
{
threestack test;
test.push(1,5);
// test.pop(1);
// test.pop(1);
int i;
for(i=0; i<101; i++)
{
test.push(2, i);
printf("%d\n", test.peek(2));
}
cout<<endl;
printf("The top of stack 1 is %d\n", test.peek(1));
// std::cout << "Hello, World!\n";
return 0;
}
C++ arrays have a fixed size at compile time.
This is why your test module works - the size (=300) is known at compile time.
That's mandatory because the size of an array is in fact part of it's type, implying that
the type of int[1] is very different from int[2].
Yet it is not known when you kind of "dynamically" create the array in the constructor.
The way out is allocating dynamic memory using the new and delete [] operators.
Even better, try to use shared_ptr, unique_ptr or auto_ptr.
This
int* buffer;
is not a declaration of an array. It is a declaration of a pointer to int.
In constructor
threestack(int stacksize_u)
{
int buffer_u[stacksize_u*3];
this->buffer = buffer_u;
this->stacksize = stacksize_u;
}
all these two statements
int buffer_u[stacksize_u*3];
this->buffer = buffer_u;
are invalid. Firest of all sizes of arrays shall be constant expressions. Secondly you assign adrress of the first element of a local array to pointer buffer. After exiting from the constructor this address will be invalid because the local array will be destroyed.
You should either allocate dynamically array using operator new and assigning its value to data member buffer or use container std::vector instead of the dynamically allocated array.
I'm using an example code given to me by another C++ coder for a project. I'm a new student of C++ language and I wondered is there a possible memory leak / bugs in this class file given to me (PlacementHead.cpp):
#include "PlacementHead.h"
#include <string>
#include <iostream>
#include <string.h>
PlacementHead::PlacementHead(int width, int height, int gap, char* s) {
width_ = width;
height_ = height;
gap_ = gap;
size_ = (width*height)+1;
set_ = new char[size_ + 1];
from_ = new int[size_ + 1];
original_ = new char[size_ + 1];
strcpy(set_,s);
strcpy(original_,s);
}
PlacementHead::~PlacementHead() {
}
int PlacementHead::getSize() { return size_; }
int PlacementHead::getHeight() { return height_; }
int PlacementHead::getWidth() { return width_; }
int PlacementHead::getGap() { return gap_; }
// Palauttaa indeksissä i olevan suuttimen
char PlacementHead::getNozzle(int i) {
return set_[i-1];
}
// Asettaa indeksissä i olevan suuttimen
void PlacementHead::setNozzle(int i, char c) {
set_[i-1] = c;
}
// Merkitsee suuttimen poimituksi poistamalla sen listasta
void PlacementHead::markNozzle(int i, int bankPos) {
set_[i-1] = ' ';
from_[i-1] = bankPos;
}
// Palauttaa seuraavan poimimattoman suuttimen indeksin
int PlacementHead::getNextUnmarkedPos() {
for (int i=0; i<size_; i++) {
if (set_[i]!=' ') {
return i+1;
}
}
return 0;
}
// Palauttaa suuttimen alkuperäisen sijainnin pankissa
int PlacementHead::getBankPos(int i) {
return from_[i-1];
}
// Plauttaa alkuperäisen ladontapaan suutinjärjestyksen
void PlacementHead::reset() {
//for (int i=0; i<size_; i++) {
// set_[i] = original_[i];
//}
strcpy(set_,original_);
}
// Tulostusmetodi
void PlacementHead::print() {
std::cout << "ladontapaa:\n";
for (int h=height_; h>0; h--) {
for (int w=width_; w>0; w--) {
int i = ((h-1)*width_)+w;
std::cout << getNozzle(i);
}
std::cout << "\n";
}
}
PlacementHead.h:
#ifndef PLACEMENTHEAD_H
#define PLACEMENTHEAD_H
class PlacementHead {
public:
PlacementHead(int size, int rows, int gap, char* s);
~PlacementHead();
int getSize();
int getHeight();
int getWidth();
int getGap();
char getNozzle(int i);
void setNozzle(int i, char c);
void markNozzle(int i, int bankPos);
int getNextUnmarkedPos();
int getBankPos(int i);
void reset();
void print();
private:
char* set_;
int* from_;
char* original_;
int size_;
int width_;
int height_;
int gap_;
};
#endif
I notice that there is dynamic allocation of memory, but I don't see a delete anywhere...is this a problem? How could I fix this if it is a problem?
Thnx for any help!
P.S.
I noticed there is no keyword class used in this example?...Can you define a class like this?
It's impossible to say without seeing the class definition (the
header); if size_, etc. are something like
boost::shared_array, or std::unique_ptr, there is no leak.
If they are simply int*, there is a leak.
Of course, no C++ programmer would write this sort of code
anyway. The class would contain std::vector<int> and
std::string. Judging from what we see here, the author
doesn't know C++.
the code has leak . the constructor allocates the memory .Destructor or some other function have to clean that before the object gets destroyed
Another problem is that your code does not obey Rule of three (links here and here)
once you will write code like:
{
PlacementHead a(0,0,0,"asdsa");
PlacementHead b(0,0,0,"asdsa");
a = b; // line 1
} // here segfault
you will get segfault, in line 1, pointers will be copied from b to a, and once you will finally have destructors, pointers will be deleted twice, which is wrong. This is called shallow copy, you need deep copy, where new array will be allocated.