Basic creation set in c++ - c++

I have tried to realize set by basic metods via struct.
This is my variant:
#include <iostream>
using namespace std;
struct Set<T> {
int n;
T[n] elements;
}
int main(){
struct Set microSet;
int oneElm, length;
cin>>length;
microSet.n=length;
for(int i=0;i<length;i++) {
cin>>oneElm;
microSet.elements[i]=oneElm;
}
for(int i=0;i<length;i++)
cout << microSet.elements[i];
return 0;
}
Compilator shows me an error related with sruct.
What've I done wrong?

Your code is illegal (and wrong in many places, so take a few days to read a good C++ book then look at some C++ reference website). You can't declare a variable length array as a member of a struct or class (and even if you could, you have the wrong syntax; some compilers support them as an extension, and C99 -but no C++ dialect- has flexible array members).
You'll better use existing standard C++ containers. If you can't use them, you need pointers (and you should prefer smart pointers).
Even if you have some compiler accepting VLAs as an extension, you probably need to dynamically allocate a memory zone for them.
I strongly recommend learning to use containers.
Don't forget to enable all warnings & debug info when compiling. With GCC, compile with g++ -Wall -Wextra -g. Use the debugger (gdb) and perhaps valgrind.

Related

Some codes are not running properly in DEV C++

I have been using DEV C++ for the last 2 months and never faced such an issue. But today when I am running the follow code, the execution screen is displaying nothing.
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
cout<<"ENTER THE LENGTH OF THE ARRAY:";
cin>>n;
int a[n];
cout<<"ENTER THE ELEMENTS OF THE ARRAY:";
for(int i=0; i<n; i++){
cin>>a[i];
}
const int N = 1e6+2;
int idx[N];
for(int i=0;i<N;i++){
idx[i]=-1;
}
int minidx = INT_MAX;
for(int i=0; i<n; i++){
if(idx[a[i]]!=-1){
minidx = min(minidx, idx[a[i]]);
}
else{
idx[a[i]]=i;
}
}
if(minidx == INT_MAX){
cout<<"NO REPEATING ELEMENT FOUND";
}
else{
cout<<"REPEATING ELEMENT FOUND AT:"<<minidx+1;
}
return 0;
}
This is the screenshot of the output screen.
Pls suggest me a solution to this problem.
I have been using DEV C++ for the last 2 months
Notice that DEV C++ is an old, non-standard conforming, and buggy compiler.
int n;
cout<<"ENTER THE LENGTH OF THE ARRAY:";
cin>>n;
int a[n];
What would happen if your user has input -1234? Arrays cannot have negative dimensions, and your code did not test that!
You deserve using a better C++ compiler
E.g. the ones (GCC or Clang) inside a Debian distribution, with a good source code editor such as GNU emacs and some good build automation tool like GNU make.
#include <bits/stdc++.h>
is wrong and non standard conforming, and is slowing down your compilation.
const int N = 1e6+2;
int idx[N];
This is not reasonable: you want more than four millions bytes on your call stack, which is often limited to a megabyte. My guess is that you are experimenting some stack overflow for your automatic variable idx
Consider using standard C++ containers, and upgrade your compiler to a decent one.
I recommend using a recent GCC (at end of 2020, this means GCC 10) compiler as g++ -Wall -Wextra -g since you want all warnings and debug info. You could even use static analysis options to g++
Once you got no warnings, use the GDB debugger to understand the behavior of your program.
Read a good C++ programming book
See this C++ reference, the documentation of your C++ compiler, and of your debugger.
Consider using tools like the Clang static analyzer on your code.
Refer to a recent C++ draft standard, such as n4659. Be afraid of undefined behavior. Take inspiration from existing C++ open source code on github or gitlab.
In a few months, if so allowed, consider coding your GCC plugin to find some bugs in your programs. Be aware of Rice's theorem.
DevC++ seems now supported by Embarcadero: https://github.com/Embarcadero/Dev-Cpp/releases checked it, and it is looking ok enough. I will assume that you are not using the 1991 version of this IDE and the compiler it came with; Of course, if you want to use it with Windows 98 then the old version might be an option,
Anyhow, I will try to list the issues in your code. Most of them are a trap for beginners:
int n;
cout<<"ENTER THE LENGTH OF THE ARRAY:";
cin>>n;
in this part, you are not forcing flushing before asking for user input. It is always a good practice to flush before user-input. How this can be an issue? Long story short you can get for example C/C++ printf() before scanf() issue
solution: c++ force std::cout flush (print to screen).
Let's continue you are using Variable-length array (VLA) here which is not supported by C++ stdandard,
int a[n];
You can check for more Why aren't variable-length arrays part of the C++ standard?
Recommend using std::vector a(n); there which it will allocate in the heap. If yo want the allocation in the stack, within standards then you either need to wait for "dynarray" (which may never be available in C++) or switch to C...
const int N = 1e6+2;
int idx[N];
for(int i=0;i<N;i++){
idx[i]=-1;
}
in the code below, you are trying to allocate a gigabyte of buffer in the stack. I suspect this is the reason why your program is not running properly. If you want a cheap hack then you can convert this allocation to "static int idx[N];" which will move this buffer to the heap. Beware using a static variable is not a good practice at all and not recommending it. Recommend either "new []" or "vector" there too,
for(int i=0; i<n; i++){
if(idx[a[i]]!=-1){
minidx = min(minidx, idx[a[i]]);
}
else{
idx[a[i]]=i;
}
}
idx[a[i]] has no boundary check. you should check the boundary for both arrays.
First of all, this is a security leak and a very bad-way of writing a program: Example of a buffer overflow leading to a security leak
Also, this part looks like it has a logic issue: Withing the boundary all the "idx" elements should be "-1" so you should never get into the else-condition (in a normal way)

Visual Studio Community 2019 requires a constant value inside square brackets [duplicate]

This question already has answers here:
Why aren't variable-length arrays part of the C++ standard?
(10 answers)
Closed 2 years ago.
I've been trying to find answers for this lately, but I just can't seem to understand why the compilers for C++ that Microsoft has been using can't compile such a code :
#include<iostream>
int main()
{
int n;
std::cin >> n;
int x[n];
}
It gives those errors :
However, this code compiles on a lot of different compilers.
Could someone point me to somewhere, I couldn't find any answers for this.
See How to make an array with a dynamic size? General usage of dynamic arrays (maybe pointers too)? for discussion on the matter. Briefly, C++ requires that raw arrays have a constexpr for their size, so they it knows how much memory to allocate for it at the moment it's declared instead of at runtime after receiving user input. Some compilers I suppose are more permissive on this.
Variable length arrays are not standard C++. Some compilers provide them as a language extension but they are not portable.
This code shouldn't compile.
In C++, arrays are statically allocated and their required memory must be specified at compile time.
Hence, a user input is not a suitable value for array declaration. If you want a dynamic array, you can try using malloc like this:
#include<iostream>
int main()
{
int n;
std::cin >> n;
int* x = (int*)malloc(n*sizeof(int));
}
This way, the array is actually stored in heap, and can have any arbitrary size, changing over lifetime of the program.
Another alternative is std::vector of course.

What are different ways of initializing the size of an array with user input in c++

I was wondering what are some alternatives to doing the following code snippet in c++.
int i;
cin >> i;
int arr[i];
I have recently started looking into competitive programming and trying to learn more.
EDIT: For those comments about this not being cpp. It compiles successfully with the makefile I am using in my class which is using gcc -std=c++11 -o a.exe main.cpp and returns to the console when I input a length of 1
array length: 1
You should use std::vector instead in C++, e.g.
int i;
cin >> i;
std::vector<int> arr(i);
BTW: VLA is not supported by C++ standard. Also see Variable Length Array (VLA) in C++ compilers
One way is:
int i = 0;
cin >> i;
auto arr = std::make_unique<int[]>(i); // #include <memory>
// Or: std::make_shared<int[]>(i);
Another way is to use std::vector:
int i = 0;
cin >> i;
std::vector<int> arr(i); // #include <vector>
Your code is not C++. It uses a C language feature (from the C99 version of the C standard) called "variable-length arrays" - where arrays on the stack can have a length determined at run-time.
Variable-length arrays are considered are dangerous and considered a rather bad idea; see:
Why aren't variable-length arrays part of the C++ standard?
If you compile your code while telling the compiler to only accept standard-compliant code, it will fail: gcc -std=c++11 -pedantic-error. Try it on GodBolt.
In C++ the size of an array is set at compile-time, period. Like other users suggested, you can use dynamic allocation to obtain a run-time-determined-length contiguous area in memory, of your choice of size: Using std::vector, std::unique_ptr, std::shared_ptr or even plain allocation with new (although the latter is not recommended).

Using malloc instead of new causes free(): invalid pointer error

For some reason compiling the following code with gcc and running the binary it produces on Ubuntu gives a free(): invalid pointer error:
#include <stdlib.h>
#include <fstream>
#include <string>
#include <iostream>
#include <sstream>
#include <ios>
#include <new>
struct arr_double_size {
double *array;
int size;
};
struct Record {
int ID;
std::string str1;
std::string str2;
int num;
struct arr_double_size values;
};
struct Record_array {
struct Record *array;
int size;
};
void Copy_Read(void) {
std::ifstream file{"in_file"};
std::ofstream new_file{"out_file"};
std::string line;
while (std::getline(file,line)) {
new_file << line << std::endl;
}
file.close();
new_file.close();
}
int main(void) {
Copy_Read();
struct Record rec;
struct arr_double_size values;
values.size = 1;
values.array = (double *)malloc(1 * sizeof(double));
values.array[0] = 72.12;
rec.ID = 2718;
rec.str1 = "Test1";
rec.str2 = "Test2";
rec.num = 1;
rec.values = values;
struct Record_array record_list;
record_list.size = 1;
record_list.array = (struct Record *)malloc(1 * sizeof(struct Record));
record_list.array[0] = rec;
return 0;
}
The contents of in_file are:
TEST TEST TEST
Strangely, commenting out the call in main to Copy_Read solves the problem, as does replacing the calls to malloc with calls to new. Running the program with gdb shows that the error occurs when attempting to assign rec to record_list.array[0]. Why does this occur? I have tried to give a minimal example here; previous, expanded versions of this code resulted in segmentation faults instead of the free(): invalid pointer error. I am aware that this is horrible code which should never be used in a serious program (I should be using standard library vector and new), but there seems to be something I do not understand and which is not well-documented (in resources accessible to beginners, anyway) about the difference between malloc and new which is the source of the problems with this code.
I do not understand about the difference between malloc and new
The you need to read much more about C++, e.g. some C++ programming book, and a good C++ reference site. Yes, C++ is a very difficult language (you'll need years of work to master it). Later, you could dive into the C++11 standard n3337 (or some more recent C++ standard). You certainly need to understand precisely the role of constructors and destructors (and explaining that takes many pages, much more than what you can reasonably expect in any StackOverflow answer).
You need to have the code of your constructors to be executed (and that is done with new but not with malloc) - and later the destructors should also be executed, before releasing the memory. Destructors are called by delete (and in many other cases) but of course not by free. Read also about the rule of five and about RAII.
You should, when possible, prefer to use smart pointers. Sometimes (e.g. for circular references) they are not enough.
Be afraid of undefined behavior.
The valgrind tool is useful to hunt memory related bugs. You should also compile with all warnings and debug info, so g++ -Wall -Wextra -g with GCC. You may also want to use static source code analyzers tools such as clang-analyzer or Frama-C. Using them may require a lot of expertise; there is no silver bullet.
Your struct Record_array is wrong: prefer to use std::vector<Record>. Read much more about standard C++ containers.
The constructor of your Record will call the constructor of str1 and of str2 (that it, the constructor of std::string-s applied to two different locations). If you don't call that Record constructor, str1 and str2 stay in some undefined state (so you have some undefined behavior as soon as you use them).
A major difference between malloc & free (for C) and new and delete (for C++) is the way constructors and destructors are involved. Of course, malloc & free are ignoring them, but not new & delete. Failure of memory allocation (e.g. when virtual memory is exhausted) is also handled differently.
PS. In practice, you should never use malloc in C++ code, except -in rare cases only- when defining your own operator new. Because malloc does not call C++ constructors (but new does). Also, please understand that C and C++ are different programming languages, and malloc is for C, not C++. Many C++ standard library implementations are using malloc in their implementation of the standard ::operator new and using free in their ::operator delete.

Can we create variable length arrays in c++

I am trying to create this simple program which displays the data of the array back to the user again.. I want to create a variable length array. In this program the user is first asked the number of elements of the array followed by the data.
The problem is that in some of the IDE this code runs completely fine but in others it gives the error that variable length array is not allowed.... So what is correct?
void main()
{
int t;
cin>>t;
int ar[t];
for(int i=0;i<t;i++)
{
cin>>ar[i];
}
for(int i=0;i<t;i++)
{
cout<<ar[i]<<"\t";
}
}
For eg. This doesn't work in Turbo C++... But runs in this IDE's
http://www.tutorialspoint.com/compile_cpp11_online.php
https://www.codechef.com/ide
Standard C++ does not support variable length arrays. Some implementations provide it as an extension but as you have already found out, relying on them makes for non-portable code.
I recommend you use a std::vector instead. It works with pure standard C++.
int size;
if (!(std::cin >> size) || (size < 0))
throw std::invalid_argument {"bad size"};
std::vector<int> numbers (size);
In GCC and Clang, you can use the -pedantic compiler switch to turn off any non-standard extensions. This will help you avoid accidentally writing non-portable code. Of course, you should also compile with -Wall, -Wextra and -Werror.