trying to get ‘sval’ to contain the string “$1” – “$500” for array indexes 0-499. in the following code, however itoa is giving me strange strings in the code below:
#include<iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
typedef struct data_t {
int ival;
char *sval;
} data_t;
void f1(data_t **d);
int main()
{
data_t *d;
d=static_cast<data_t*>(malloc(500)); //is this even needed?
d = new data_t[500];
f1(&d);
}
/* code for function f1 to fill in array begins */
void f1(data_t **d)
{
int i;
char str[5];
for (int i=0; i<500; i++)
{
(*d)[i].ival=i+1;
itoa (i,str,10);
(*d)[i].sval= str;
}
}
it also seems itoa has been depreciated, but that was what i got when i googled int to string
You don't need ltoa, cout should be just fine. Why do you need to keep the number and its string representation in the array? when you do cout << 10 you get "10" on the output, you don't need any conversions of your own
You, on the other hand, do ltoa without allocating any memory for the strings, which is not healthy as you have probably noticed. You use a local variable (the same, for all the 500 array members), which you try to access after you exit the function - a big no-no, its undefined behavior.
And:
d=static_cast<data_t*>(malloc(500)); //is this even needed?
d = new data_t[500];
No. Not only not needed - shouldn't be there at all! When in C++ - use new and delete, never malloc, that's a C function.
Related
I have got class "student.cpp"
#include <iostream>
#include "student.h"
using namespace std;
void student::setMarks(int m1, int m2) {
mark1 = m1;
mark2 = m2;
};
void student::setName(char *n) {
name = n;
};
int student::calc_media(void){
return (mark1+mark2)/2;
};
void student::disp(void){
cout << "Student:" << name << " \n media:"<< calc_media() <<"\n";
};
student::student(){
mark1 = 0;
mark2 =0;
name = "";
};
Header file "student.h":
ifndef CLASY_STUDENT_H
#define CLASY_STUDENT_H
#endif //CLASY_STUDENT_H
class student{
char *name;
int mark1, mark2;
public:
void setName(char *n);
void setMarks(int m1, int m2);
void disp(void);
int calc_media(void);
student();
};
And "main.cpp":
#include <iostream>
#include "student.h"
using namespace std;
int main() {
student s;
char* n;
int m1, m2;
cout << "Enter name:";
cin>> n;
cout << "Enter marks of two subjects:";
cin>> m1;
cin>> m2;
s.setName(n);
s.setMarks(m1, m2);
s.disp();
return 0;
}
I am running this usign Clion and Cmake is :
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
set(SOURCE_FILES main.cpp student.cpp student.h student.cpp student.h)
But when I run, it asks for name, but when I type something then I have got a memory fragmentation error. Whats wrong?
And could someone by the way tell me if it looks okey for C++? I am trying to switch from java to c++.
char* n;
...
cin>> n;
n is a pointer, supposed to point at a particular piece of memory. But you never set it. So it has some undefined value, pointing who-knows-where into some memory that you end up trying to overwrite. Most likely memory you are not allowed to overwrite, causing a segfault.
Don't try to use char* if you don't yet know about manual memory management (and once you do, you'll understand why not to). Use std::string.
From a quick glance, you can pretty much replace char* everywhere with std::string (as long as you #include <string>).
Similar to what others are saying, your variable n is an uninitialized pointer. Pointers, as the name suggests, are just signposts to a particular location in memory - the tell the CPU "go to this memory location for variable x".
Say you have an integer variable var, which is declared like this:
int var;
That variable occupies memory and you can assign it a value like this:
var = 5;
You can also declare a pointer to an integer like this:
int * var_ptr;
Now assuming var_ptr points to a valid integer I can assign a value to it like this:
*var_ptr = 5;
This says "put the number 5 at the memory location pointed to by var". However if var_ptr has not been initialized then it will point to a random location in memory that may overwrite something important, or attempt to write to a protected memory address causing a protection fault (segfault). This is what is happening in your code.
To initialize var_ptr to point to the address of var, we can do this:
var_ptr = &var;
The ampersand is the "address of" operator - it says "don't get me the value of var but instead get me the address of the memory location where var is stored".
So, to prevent your problem, you must initialize n to some valid memory location where you are able to safely write some data.
There are a few ways to do this. As #Stefan points out you can declare n to be a character array:
char n[20];
As #BobTFish points out you need some way to make sure that your input doesn't exceed the size of your array (20 bytes in this case). The solution is std::cin.width(20).
As #BobTFish also mentions, you could also using a std::string, like this:
std::string n;
std:cin >> n;
The std::string object will automatically take care of memory allocation.
If you really must use a char *, you can either take the address of a char array (here I take the address of the first element of the array):
char n_array[20];
char *n = &n_array[0];
std::cin.width(20);
std::cin >> n;
You could also use dynamic memory allocation:
char *n = new char[20];
std::cin.width(20);
std::cin >> n;
delete n;
Notice that if you use dynamic memory allocation you must free the memory using delete when you are done otherwise there will be a memory leak. Local variables (like the array) are allocated on the stack and therefore are automatically freed when the function returns. For this reason, and the overhead of dynamic memory allocation, you would be insane to use it here.
I've been trying to solve an easy problem, but I can't figure why my program doesn't work. I want to concatenate a string.
Can you help me? If so, can you also explain me why it doesn't work?
#include <iostream>
#include <cstring>
#include <fstream>
using namespace std;
ifstream in("sirul.in");
ofstream out("sirul.out");
char a[4000]="a",b[4000]="b",aux[4000];
int main()
{ int n,i;
in>>n;
if(n==1)out<<"a";
if(n==2)out<<"b";
for(i=3;i<=n;i++)
{
aux=strcpy(aux,b);
b=strcat(b,a);
a=strcpy(a,aux);
}
return 0;
}
strcpy and strcat work directly on the pointer you pass in as the first argument, then also return is so that you can chain calls. As such, assigning their result back to the destination pointer is redundant. In this case, it's also invalid, as you can't reassign an array.
The fix is to just not assign the return value of those calls:
strcpy(aux,b);
strcat(b,a);
strcpy(a,aux);
However, since you are using C++, you should use std::string instead, which gives you nice value semantics for your string data.
you can not do (see 2)
char b[4000]="b";
char aux[4000];
aux /* 2 */ = strcpy(aux /* 1 */ , b);
because aux is not a pointer, but array. you can pass it as pointer argument (see 1), but you can not "collect" the result "inside" aux (see 2).
As other suggested, just remove "collection" and it will work as you expect.
char b[4000]="b";
char aux[4000];
strcpy(aux /* 1 */ , b);
// or even:
const char *s = strcpy(aux /* 1 */ , b);
Also you are mixing C and C++ in one file.
Also probably there is possibility for buffer overflow.
#include <iostream>
#include <cstring>
#include <fstream>
using namespace std;
ifstream in("sirul.in");
ofstream out("sirul.out");
char a[4000]="a",b[4000]="b",aux[4000];
int main()
{
int n,i;
cin>>n;
if(n==1)cout<<"a";
if(n==2)cout<<"b";
for(i=3;i<=n;i++)
{
strcpy(aux,b);
strcat(b,a);
strcpy(a,aux);
}
return 0;
}
check out definition os strcpy, in should be cin and out should be cout
I have got a structure
class pyatno {
int pyatnoNumber;
int locX, locY;
bool possible;
char *number;
char pyatnoView[4][4];
}
the idea is to make a function, that would return an array of pyatno.pyatnoView objects, but there is a mess. I don't understand how exactly I can get access to this "property". I am not strong in c++, so if it isn't real, or i am talking something wrong, explain please, cause I am really stacked in this question.
As you mentioned that you are not very strong with c++, and your question is rather unclear, here are several suggestions.
To get access to a class's attributes, c++ has the notion of visibility; The default visibility is private, that is, attributes and functions will not be visible outside of the class:
class Foo {
int some_value;
};
There are several ways you can retrieve data from an object, however to put it simply, you should either make the attribute public:
class Foo {
public:
int some_value;
};
or expose it via accessors/mutators:
class Foo {
int some_value;
public:
int get_some_value() { return some_value; }
void set_some_value(int v) { some_value = v; }
};
Another thing to note is that you can not return arrays! In c++, when an array passes a function boundary (that is to say, passed as a parameter to, or returned from), and in a lot of other cases, an array will 'decay' in to a pointer. For example, the following is how I would pass an array of characters (otherwise known as a c-string) to a function:
#include <iostream>
using namespace std;
void print_cstr(const char *cstr) {
cout << cstr << endl;
}
int main() {
const char my_cstr[20] = "foo bar baz qux";
print_cstr(my_cstr);
return 0;
}
So what happens for N-dimensional arrays? Well, if char[1] decays to char*, then char[1][1] will decay to char**, and so on. You might have noticed this with the older main signature in C programs, which is used to pass an array of strings representing arguments passed to the program:
int main(int argc, char **argv) { ... }
It is very important that you realise that this really is no longer an array. C style strings are a bit special, in that they are conventionally terminated with a null byte \0, which means that you can usually tell where the end of the string is, or how long it is. However, you no longer have any information on how long the array is! For example, this is completely legal:
#include <iostream>
using namespace std;
void bad_fn(const int *nums) {
for (unsigned i = 0; i < 20; ++i) {
cout << "num " << i << " = " << nums[i] << endl;
}
}
int main() {
const int my_nums[5] = { 1, 2, 3, 4, 5, };
bad_fn(my_nums);
return 0;
}
Your function will end up reading memory beyond the bounds of the array, as it has no way of knowing where the array begins or ends (after all, array indexes are just pointer arithmetic). If you do not want to have to worry about keeping track of, and passing around the length of your array (and I would suggest that you do not!), please look at using one of the C++ standard library's containers. std::vector and std::array are two examples that would fit in the use case you have provided, and you can find decent documentation for them here.
What should be the proper way of doing this? Here's an example code of what I tried.
main
const int SIZE = 10;
char a[10][SIZE]; //assume this array already hold some character strings
fnc(a[2][SIZE]);
function
void fnc(char a[SIZE]){
cout << a;
}
I feel that I might be close, but I couldn't get it to work. Any help would be appreciated!
the function call in main should not be:
fnc(char a[2][SIZE]);
i am guessing you want to print the string at a[2]. Hence your function call should be:
fnc(a[2]);
Ok you want to pass an element from 2d char array to a function. So just pass two arguments to your function which indicate the position of your element.void fnc(int p1,int p2)
Your whole code will look like this.
const int SIZE = 10;
char a[10][SIZE];
fnc(2,0);
function
void fnc(int p1,int p2){
cout << a[p1][p2];
}
Hope this helps
You can pass 2D array like this:-
char array[10][10];
void passToFunc(int a[][10])
{
// ...
}
passToFunc(array);
Sorry for mis-interpretation:-
You can do it by :-
void passElement( char x )
{
//do something with x.
}
passElement( arr[1][1] ); //assume you want to pass 2nd element of 2nd 1-dimensional array.
Hope that helps :)
Your application never initializes the strings so there may be garbage being printed out. Here is an example that I did that works for me. Its a C++ app written using visual studio 2013.
Note that I initialized the strings to only 9 places in a 10 place array.
That is to account for the null terminator required for each string.
I hope this helps.
// TestApp.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <string.h>
#include <iostream>
#include <windows.h>
using namespace std;
const int xSIZE = 10;
void fnc(char*);
int _tmain(int argc, _TCHAR* argv[])
{
char a[10][xSIZE];
strcpy(a[1], "012345678");
strcpy(a[2], "abcdefghi");
fnc(a[2]);
return 0;
}
void fnc(char a[])
{
cout << a<<endl;
}
Hello
Can somebody explain why second cout in func(char *p) doesn't work:
#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
char *strhex(char *str);
char *func(char *p);
int main()
{
char *ptr;
char *p=strhex("d");
cout<<"main:"<<p<<endl;
cout<<func(p)<<endl;
system("PAUSE");
return 0;
}
char *func(char *p)
{
cout<<"func1:"<<p<<endl;
char buffer[500]="";
char *zbuffer = buffer;
cout<<"func2:"<<p<<endl; ///doesn't work
return zbuffer;
}
char *strhex(char *str)
{
char buffer[500]="";
char *pbuffer = buffer;
int len = strlen( str );
for( int i = 0; i < len ;i++ )
{
itoa(str[i],pbuffer,16);
pbuffer +=2;
};
*pbuffer = '\0';
pbuffer=buffer;
return pbuffer;
}
Edit:
i'm using DEV C++ 4.9.9.2 on Windows
One big problem here is that strhex is returning a pointer to a local variable (buffer[]). This variable goes out of scope at the end of the function, so the return value points at undefined memory contents that can be overwritten at any time.
Your entire code doesn't work. Both functions return pointers to local arrays, which don't point to anything valid after the function returns. That causes undefined behavior. Since the value of p is one of these invalid pointers, you can't depend on it to be anything at any particular time — that memory probably gets overwritten during func(). You need to either new[] and delete[] the appropriate memory or, preferably, use a proper C++ data structure like std::string.
it looks like it is working but the second cout in main is not printing out a value because you are returning an empty buffer.
Adding to others answers:
You need not reset pbuffer to point to the start of the array and then return it's value:
pbuffer=buffer;
return pbuffer;
you can just say
return buffer;
the array name is also a pointer(pointer to the first element of the array.