Memory Corruption C++ - c++

After some criticism regarding this post I have decided to try another solution to test my issue.
I purpose of the code below was to save user input into an array and then output it when user types in exit. I am relatively new to C++ which means that I am aware that this is a code issue.
The constraints for this code are to not use STL or strings.
I have attached the code below which does not give the desired output, instead it prints out "exit" the number of times equal to the number of items stored in the array.
#include <iostream>
char * textArr[1000];
int lineCount = 0;
void saveText(char * text) {
textArr[lineCount] = new char(1000);
strcpy(textArr[lineCount], text);
}
int main()
{
char * line = new char(1000);
while (lineCount < 1000) {
std::cin.getline(line , 1000);
if (strcmp(line, "exit") == 0) {
break;
}
saveText(line);
lineCount++;
}
for (int i = 0; i < lineCount; i++) {
std::cout << textArr[i] << std::endl;
}
delete(textArr);
delete(line);
return 0;
}

Related

How can I return a calloc pointer from C into C++?

I am working on a personal project that requires me to call C functions from C++ code. These C functions return a calloc() pointer.
1t5.h
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
char * prob1(char * number);
1t5.c
#include <1t5.h>
char * prob1(char * number) {
int ni = atoi(number);
char prompt[] = "hello\n";
char * answer = (char*)calloc(ni, sizeof(prompt));
for (int i = 0; i < ni; i++) {
strcat(*answer, prompt);
}
return answer;
}
That C code is supposed to return a given number of "hello\n".
linking.cpp
string Link::problemRouting(string problem, vector<string> contents) {
string answers = "";
char * ca;
int pi = stoi(problem);
for (int i = 0; i < contents.size(); i++) {
ca = cv.stringToChar(contents[i]);
// C Standard
if (pi <= 5) {
char * answer;
switch(pi) {
case 1:{
answer = prob1(ca);
}
case 2: {
answer = prob2(ca);
}
case 3: {
answer = prob3(ca);
}
case 4: {
answer = prob4(ca);
}
case 5: {
answer = prob5(ca);
}
}
cout << answer;
answers+=answer;
free(answer);
}
}
return answers;
}
This C++ code takes the return value and saves it to store into a text file later.
The problem is when I input a number, lets say 257, then the return value is 257, and not a ton of "hello\n".
Thanks to #Remy Lebeau for the answer.
My code contained many chances for memory to leak, resulting in a mess of a return value.
string Link::problemRouting(string problem, vector<string> contents) {
string answers = "";
char * ca;
int pi = stoi(problem);
for (int i = 0; i < contents.size(); i++) {
ca = cv.stringToChar(contents[i]);
// C Standard
if (pi <= 5) {
char * answer;
switch(pi) {
case 1:{
answer = prob1(ca);
break;
}
}
free(ca);
cout << answer;
answers+=answer;
free(answer);
}
}
return answers;
}

Unscrambling words in C++ using pointers

for my csc 102 class I have to create a program that will replace certain letters with others in a text file. The file holds five words and I have to use a class system. This sounds simple enough to me, but my variables in the class have to be pointer variables. Being that all of my classes are online now, trying to use my professors handwritten notes on canvas is all I have to explain how he wants projects done. I sort of understand what a pointer is. The pointer holds the address of a value. You have to dereference it with * to get the value stored there. However, I just don't see how pointers are to be used in this problem. This is the first prompt out of four and I just don't get what i'm supposed to do with the pointers. I will attach my code below and what the prompt asks me to do. I appreciate any help.
Prompt:
Problem 1: A computer keyboard has defect (like speech defect in humans) in reading for ‘p’ /’P’ as ‘f’/’F’ or vice versa and ‘n’/’N’ as ‘l’/’L’ or vice versa
Create a class with pointer variables that would correct the spelling of each word from the input.txt print them in in an output.txt.
Class Header file:
#pragma once
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
class keyfix
{
char* input;
char* output;
string* word;
char* wordarray[10];
public:
keyfix();
~keyfix();
void readfile(ifstream&);
void correctspelling(ofstream&);
void outputfile();
void print()const;
};
class implementation file:
#include "keyfix.h"
keyfix::keyfix() {
input = new char;
output = new char;
*input = 'o';
*output = 'o';
word = new string;
*word = "empty";
*wordarray = new char;
}
keyfix::~keyfix() {
delete input;
delete output;
delete word;
input = output = NULL;
word = NULL;
}
void keyfix::readfile(ifstream& a) {
for (int i = 0; i < 10; i++) {
a >> wordarray[i];
}
}
I have an ifstream object and an ofstream object in main.
In my mind, I planned to use a character array instead of a string so that I could change each incorrect letter without using functions we haven't yet covered like anything in <algorithms>. I am in real need of some direction here. I am sure some of y'all can look at my code and tell, but I get a nullptr error whenever I try to test the read file function.
EDIT: I am now writing it with wordarray as a plain char array. It may be accepted this way, it may not be.
Also, the size is 10 because the file is provided and the largest word only has 10 letters.
As recommended in the comments, I wrote the program without pointers, and then changed a variable to a pointer type in my class. Here is the final project for any future students who happen to have this exact problem. (I saw the problem on chegg so I know he uses it commonly)
#pragma once
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
class keyfix
{
char* input;
char wordarray[10];
public:
keyfix();
~keyfix();
void readfile(ifstream&);
void correctspelling(ofstream&);
void print()const;
};
#include "keyfix.h"
keyfix::keyfix() {
input = new char;
*input = 'o';
wordarray[10];
}
keyfix::~keyfix() {
delete input;
input = NULL;
}
void keyfix::readfile(ifstream& a) {
for (int i = 0; i < 10; i++) {
wordarray[i] = NULL;
}
a >> wordarray;
}
void keyfix::correctspelling(ofstream& b) {
for (int index = 0; index < 10; index++) {
*input = wordarray[index];
if (*input == 'f') {
wordarray[index] = 'p';
}
else if (*input == 'F') {
wordarray[index] = 'P';
}
else if (*input == 'p') {
wordarray[index] = 'f';
}
else if (*input == 'P') {
wordarray[index] = 'F';
}
else if (*input == 'n') {
wordarray[index] = 'l';
}
else if (*input == 'N') {
wordarray[index] = 'L';
}
else if (*input == 'l') {
wordarray[index] = 'n';
}
else if (*input == 'L') {
wordarray[index] = 'N';
}
b << wordarray[index];
}
b << endl;
}
void keyfix::print()const {
for (int i = 0; i < 10; i++) {
cout << wordarray[i];
}
cout << endl;
}
#include"keyfix.h"
//if input is f or F, output p or P
//if input is n or N, output l or L
//if input is p or P, output f or F
//if input is l or L, output n or N
int main() {
ifstream infile;
infile.open("input.txt");
ofstream outfile;
outfile.open("output.txt");
keyfix object;
for (int i = 0; i < 5; i++) {
object.readfile(infile);
object.correctspelling(outfile);
object.print();
}
}

Shifting an array of structs C++

I am quite new to c++ programming and data structures and really need some help. I am working on an assignment where I have a text file with 100 lines and on each line there is an item, a status(for sale or wanted), and a price. I need to go through the text file and add lines to an array of structs and as I add lines I need to compare the new information with the previously submitted information. If there is a line that is wanted and has a price higher than a previously input item that is for sale then the item would be removed from the struct and the array of structs shifted.
The place that I am having trouble is in actually shifting all the structs once a line that satisfies the condition is found.
My issue is that when I try to shift the array of structs using the second for loop nothing happens and I just get null structs and nothing seems to move.
Please if you guys can offer any help it would be greatly appreciated.
Below is the code of the text file and my current code.
#include<iostream>
#include<fstream>
#include <string>
#include <algorithm>
#include <sstream>
using namespace std;
struct items
{
string type;
int status;
int price;
} itemArray [100];
int main(int argc, char *argv[]) {
int x = -1;
//int chickenCount = 0;
int counter = 0;
int itemsSold = 0;
int itemsRemoved = 0;
int itemsForSale = 0;
int itemsWanted = 0;
string itemType;
int itemStatus = 0;
int itemPrice = 0;
int match = 0;
ifstream myReadFile( "messageBoard.txt" ) ;
std::string line;
//char output[100];
if (myReadFile.is_open()) {
while (!myReadFile.eof()) {
getline(myReadFile,line); // Saves the line in STRING.
line.erase(std::remove(line.begin(), line.end(), ' '), line.end());
//cout<<line<<endl; // Prints our STRING.
x++;
std::string input = line;
std::istringstream ss(input);
std::string token;
while(std::getline(ss, token, ',')) {
counter++;
//std::cout << token << '\n';
if (counter>3){
counter =1;
}
//cout << x << endl;
if (counter == 1){
itemType = token;
//cout<< itemType<<endl;
}
if (counter == 2){
if (token == "forsale"){
itemStatus = 1;
//itemsForSale++;
}
if (token == "wanted"){
itemStatus = 0;
//itemsWanted++;
}
//cout<< itemStatus<<endl;
}
if (counter == 3){
itemPrice = atoi(token.c_str());
//cout<< itemPrice<<endl;
}
//cout<<"yo"<<endl;
}
if (x >= 0){
for (int i = 0; i<100;i++){
if (itemArray[i].type == itemType){
//cout<<itemType<<endl;
if(itemArray[i].status != itemStatus){
if (itemArray[i].status == 1){
if(itemPrice>=itemArray[i].price){
itemsSold++;
match =1;
//itemArray[i].type = "sold";
for (int j=i; j<100-1;j++){
//cout<<j<<endl;
itemArray[j].type = itemArray[j+1].type;
itemArray[j].status = itemArray[j+1].status;
itemArray[j].price = itemArray[j+1].price;
}
i =i-1;
break;
}
}
if (itemArray[i].status == 0){
if(itemArray[i].price>=itemPrice){
itemsSold++;
match = 1;
//itemArray[i].type = "sold";
for (int j=i; j<100-1;j++){
//cout<<j<<endl;
itemArray[j].type = itemArray[j+1].type;
itemArray[j].status = itemArray[j+1].status;
itemArray[j].price = itemArray[j+1].price;
}
i=i-1;
break;
}
}
}
}
}
}
if (counter == 3 && match == 0){
itemArray[(x)].type = itemType;
itemArray[(x)].status = itemStatus;
itemArray[(x)].price = itemPrice;
}
match = 0;
// cout << itemArray[x].type << " " << itemArray[x].status<<" "<<itemArray[x].price<<endl;
}
for(int i=0;i<100;i++){
cout<<itemArray[i].type<< " "<<itemArray[i].status<<" "<<itemArray[i].price<<endl;
}
//cout<<itemArray[1].price<<endl;
cout << itemsSold<<endl;
}
myReadFile.close();
return 0;
}
text file: https://drive.google.com/file/d/0B8O3izVcHJBzem0wMzA3VHoxNk0/view?usp=sharing
Thanks for the help
I see several issues in the code, but without being able to test it, I think the main problem is that you always insert new elements at position 'x' which correspond to the currently line read from the file, without taking into account any shift of elements done. You should insert the new element at the first empty slot (or just overwrite the old element instead of shifting everything).
An other issue is that you do not initialize the status and price in your array.
The best way would be to rewrite the code by using more standard C++ features, for example:
replace the items structure by a class with a constructor defining default values
use object copy (there is no need to copy a struct element by element)
use standard C++ containers like a list (see http://www.cplusplus.com/reference/list/list/) which has insert and erase methods

OpenCL : pass two String to kernel, return nothing

I'd like to pass two String to an OpenCL kernet, and print text directly from it.
So far, i have this :
int main(void) {
Context(CL_DEVICE_TYPE_GPU);
static const unsigned elements = 1000;
vector<string> dataA;
for (int i = 0; i < elements; i++) {
dataA.push_back("a");
}
vector<string> dataB;
for (int i = 0; i < elements; i++) {
dataB.push_back("b");
}
Buffer a(begin(dataA), end(dataA), true, false);
Buffer b(begin(dataB), end(dataB), true, false);
Program addProg(R"d(
kernel
void add(string a, string b) {
unsigned idx = get_global_id(0);
c[idx] = 2.0;
}
)d", true);
auto add = make_kernel<Buffer, Buffer>(addProg, "add");
add(EnqueueArgs(elements), a, b);
system("pause");
}
This code crashes at runtime without explanation.
How can i debug this, and is it possible to print text from withn the kernel and display it on screen ?
OK, so it sounds like you want to pass an array/vector of strings to a kernel, and have each work-item in the kernel process a different string. You can't really do this with the STL vector and string classes since these don't work inside OpenCL kernels, so the easiest thing to do would be to instead use a flattened C array of characters (with all of the strings in one array).
I've modified your program below to do this. Basically, we set the maximum number of characters any string will need (assuming you know what this is) in the charsPerString variable. We then allocate an array with elements*charsPerString characters, and initialise the strings with a single character as you were doing. The i-th string starts at index i*charsPerString. We can then pass this to the kernel as a single buffer.
The kernel then has each work-item print out the first character in each of the two strings it is passed using printf, computing the start of its string in the same way as above.
I've also added the typical C++ error checking approach with exceptions, which will display any of the OpenCL errors that might occur. I've tested this on my own laptop, and it works, printing out:
0 has characters a and b
1 has characters a and b
2 has characters a and b
3 has characters a and b
4 has characters a and b
(which is what we would expect).
Hopefully you should be able to extend this to your own use cases.
#define __CL_ENABLE_EXCEPTIONS
#include <CL/cl.hpp>
#include <iostream>
using namespace cl;
using namespace std;
int main(void) {
try {
Context(CL_DEVICE_TYPE_GPU);
static const unsigned elements = 1000;
static const unsigned charsPerString = 16;
char *dataA = new char[elements*charsPerString];
for (int i = 0; i < elements; i++) {
dataA[i*charsPerString] = 'a';
}
char *dataB = new char[elements*charsPerString];
for (int i = 0; i < elements; i++) {
dataB[i*charsPerString] = 'b';
}
Buffer a(dataA, dataA+elements*charsPerString, true, false);
Buffer b(dataB, dataB+elements*charsPerString, true, false);
Program addProg(R"d(
constant unsigned charsPerString = 16;
kernel
void add(global char *a, global char *b) {
unsigned idx = get_global_id(0);
printf("%d has characters %c and %c\n",
idx, a[idx*charsPerString], b[idx*charsPerString]);
}
)d");
try {
addProg.build();
}
catch (Error err) {
if (err.err() == CL_BUILD_PROGRAM_FAILURE) {
cout << "OpenCL build failure:" << endl;
cout << addProg.getBuildInfo<CL_PROGRAM_BUILD_LOG>(Device::getDefault());
}
throw err;
}
addProg.build();
auto add = make_kernel<Buffer, Buffer>(addProg, "add");
add(EnqueueArgs(elements), a, b);
CommandQueue::getDefault().finish();
delete[] dataA;
delete[] dataB;
}
catch (Error err) {
cerr << "ERROR: " << err.what() << " (" << err.err() << ")" << endl;
}
system("pause");
}

Returning string from a function causing formatting issues

It's supposed to look like this: http://i.imgur.com/gko501E.png
Instead it looks like this: http://i.imgur.com/ISwqyD8.png
When I take the code out of the function and use it in the main class it works properly. However once I put it in this function the formatting problems occur, it also isn't filtering like it's supposed to. This program is supposed to take user input, store it in a string, remove all non-alphabetical characters, capitalize the vowels, and then space it out based on user defined variables given in the command line. It's also supposed to accept files as input in the command line, such as: 'program 5 8 < file'.
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <cstdlib>
#include <fstream>
#include <sstream>
using namespace std;
//make vowels uppercase
string filter(string input)
{
size_t found = input.find_first_of("aeiou");
while (found != string::npos)
{
if (islower(input[found]))
{
input[found] = toupper(input[found]);
found = input.find_first_of("aeiou", found + 1);
}
}
//Make consonants lowercase
size_t foundLower = input.find_first_of("BCDFGHJKLMNPQRSTVWXYZ");
while (foundLower != string::npos)
{
if (isupper(input[foundLower]))
{
input[foundLower] = tolower(input[foundLower]);
foundLower = input.find_first_of("BCDFGHJKLMNPQRSTVWXYZ", foundLower + 1);
}
}
//remove punctuation
for (int i = 0, len = input.size(); i < len; i++)
{
if (!isalnum(input[i]))
{
input.erase(i--, 1);
len = input.size();
}
}
return input;
}
int main(int argc, char* argv[])
{
int wordSize;
int wordSizeCounter;
int wordCounter = 0;
int rowSize;
//char letter;
wordSize = atoi(argv[1]);
rowSize = atoi(argv[2]);
ifstream inFile;
inFile.open(argv[3]);//open the input file
stringstream strStream;
strStream << inFile.rdbuf();//read the file
string test = strStream.str();//str holds the content of the file
if (!inFile) test = cin.get() ; // Read first character
//Begin filter for files
while (!test.empty())
{
filter(test);
if (test.length() < wordSize) //make sure we don't go out-of-bounds
{
wordSize = test.length();
}
cout << test.substr(0, wordSize);
cout << " ";
if (test.length() >= wordSize) //again, make sure we don't go out-of-bounds
{
test = test.substr(wordSize);
}
else
{
test = " ";
}
wordCounter++;
if (wordCounter == rowSize)
{
cout << std::endl;
wordCounter = 0;
}
if(test.empty())
{
test = cin.get();
}
}
cout << endl;
return 0;
}