Shift elements of an array

Ö

Öö Tiib

In the C++ TSandard arrays are described in section 8.3.4

Yes the raw arrays but for example the "Numeric arrays" of C++ library
are described in 26.6 of C++ Standard. Why you call it "TSandard"?

Also note that being wrong in lot of posts does not achieve any higher
qualities of wrongness.
 
V

Vlad from Moscow

вторник, 8 октÑÐ±Ñ€Ñ 2013 г., 18:39:13 UTC+4 пользователь Öö Tiib напиÑал:
Yes the raw arrays but for example the "Numeric arrays" of C++ library

are described in 26.6 of C++ Standard. Why you call it "TSandard"?



Also note that being wrong in lot of posts does not achieve any higher

qualities of wrongness.



One more if you are unsable to understand from the first time. The notion of array is well defined in C++ Standard. It is a derived type that has a special syntax for definition of objects of this type.

std::valarray and as for example std::array are not arrays. They are template classes. For example valarray is declared the following way

template<class T> class valarray;

Their names are simply some conventional names that help users to understand what they are designed for. They can have any other names as any other classes have. If for example you will name some you class as giraffe it does not mean that giraffe is your class.
 
V

Vlad from Moscow

вторник, 8 октÑÐ±Ñ€Ñ 2013 г., 18:45:09 UTC+4 пользователь David Brown напиÑал:
Hey, you got your posting right! You will find a lot more people will

talk to you now. All you need to do is change your abusive and

argumentative attitude, and stop trying to dictate to people that have

been doing this stuff probably from before you were born.



We all know what C-style arrays are in C++. We know of their

capabilities and limitations. Most of us also know what the generic

term "array" means, and what classes implement arrays, and when a class

is an array or not.



Once you have understood the difference between the specific C-style

arrays, and the generic term array referring to a particular type of

container, then we can make progress (probably by ending this thread).


The problem is that you and similar to you are simply trolls.

When I pointed out that std::string is not an array I meant that if the original assignment says to write program using arrays when you should use an array and not some type of a container. Because arrays have special methodsthat you can apply to them and has some restrictions. So the code written for arrays will differ from the code written for example for std::string. At least arrays have no methods such as size() or erase().

I do not see any sense to feed such trolls as you any more. So you may continue your word diarrhea without me.
 
R

Rosario1903

Hey, you got your posting right! You will find a lot more people will
talk to you now. All you need to do is change your abusive and
argumentative attitude, and stop trying to dictate to people that have
been doing this stuff probably from before you were born.

We all know what C-style arrays are in C++. We know of their
capabilities and limitations. Most of us also know what the generic
term "array" means, and what classes implement arrays, and when a class
is an array or not.

Once you have understood the difference between the specific C-style
arrays, and the generic term array referring to a particular type of
container, then we can make progress (probably by ending this thread).

for me array are only raw array...
something as

char a[59], *a="1234", a[]={1,2,3,4,0} etc
or the mem malloc give to a pointer as
int *b;

b=malloc(15*sizeof *b)
if b!=0
b point to one array of 4 int element
etc
 
R

Rosario1903

char a[59], *a="1234", a[]={1,2,3,4,0} etc
or the mem malloc give to a pointer as
int *b;

b=malloc(15*sizeof *b)
if b!=0
b point to one array of 4 int element ^^^^^^
etc

b array of 15 int elements
yes i make error even in simple points
it is a miracle how the compiler compile and the cpu execute
 
V

Vlad from Moscow

вторник, 8 октÑÐ±Ñ€Ñ 2013 г., 19:09:09 UTC+4 пользователь Rosario1903 напиÑал:
On Tue, 08 Oct 2013 16:45:09 +0200, David Brown wrote:




for me array are only raw array...

something as



char a[59], *a="1234", a[]={1,2,3,4,0} etc

or the mem malloc give to a pointer as

int *b;



b=malloc(15*sizeof *b)

if b!=0

b point to one array of 4 int element

etc

You are right. The notion of array is well defined in C/C++. It is a derived type that has special syntax and semantic of declarations of its objects.

For example name valaaray is simply a name of a template class. You may define your own classes with the same name valarray that will have nothing common with the C/C++ notion of arrays. For example

#include <iostream>

template <class T = void>

struct valarray
{
valarray()
{
std::cout << "Hello, World\n";
}
};

namepsace OneMore
{
template <size_t N = 3>
struct valarray
{
valarray()
{
for ( size_t i = 0; i < N; i++ ) std::cout << "Hello, World\n";
}
};
}

int main()
{
valarray<> v1;
OneMore::valarray<> v2;
}

These classes have nothing common with the notion of array in C++. You may use any names for your classes if they are not reserved words of the language. And even you will name some your class as array it does not mean that it is array.:)
 
G

Geoff

mya **bi=0;
u32 membi=0;
u32 index=0;

void fill_bi(mya* a)
{mya *r, **j;
u32 i;
if(index<=membi) ^^^^^^^^^^^^^^^
if(index>=membi)

{if(membi>0xFFFFF) exit(-1);
i=membi+128; /* 128 0..127 */
j=(mya**)realloc(bi, i*sizeof *j);
if(j==0) exit(-1);
bi=j; membi=i;
}
bi[index]=a;
++index;
}

Perhaps you should stop writing unintelligible crap and start writing
in the language of the compiler. Then you will won't be correcting
your own code twenty minutes after you write it.
 
V

Vlad from Moscow

вторник, 8 октÑÐ±Ñ€Ñ 2013 г., 19:29:51 UTC+4 пользователь David Brown напиÑал:
On 08/10/13 17:01, Vlad from Moscow wrote:


The OP gave no information about any particular type of array.

Sometimes a string can be treated as an array of characters, and

sometimes an array of characters can be treated as a string (noting, of

course, that there are many types of "string" in C++).

You even do not understand what "any particular type of array" means in C/C++. Any particulat type of an array means simply the type of array elementsand number of dimensions and sizes of the array and nothing more.

You are hung up on the idea that "array" means only specific C-style

arrays. This is simply not true, and the OP certainly did not restrict

the question to that kind of array.

There is only ONE definition of the notion of arrays in C/C++. Do you have not understood? I am repeating one more for such trolls as you: there is only one notion of arrays defined in C/C++. Do you have not understood yet? Do you need that I repeat one more?
 
M

Martin Shobe

This is probably pointless, but here goes.

It is simply is very silly and bad code. The memory allocated and deallocated at least two times.And this code demonstrates only one intention that the author is unable to write programs.

In this simple function that contains only two lines in the body the author made three serious errors.

First the function has undefined behaviour because its second parameter is defined as int. So any value of type std::string::size_type that can not be fit into int will result in undefined behaviour of the function.

Technically that's a problem with the caller.
Second, the interface of the function is inconsistent with the interface of std::basic_string. See the description of std::basic_string in the C++ Standard.

And that's a problem because?
Third, this function allocates and deallocates memory at least two times. As a result 1) the memory will be fragmented; 2) it is possible that allocating of memory will fail for large strings.
And it is a stupidy to allocate a new memory then the original string has enough memory that to do the operation "in place".

On the implementations I have available, this function
allocated/deallocated memory at most once. For the small n in the
example, it didn't perform any memory allocations.

Still, I do find I prefer the following.

void shift_left(string & s, int n)
{
s.erase(0, n);
s.append(n, ' ');
}

This results in zero allocations regardless of n and I find it clearer.

[snip]

Martin Shobe
 
V

Vlad from Moscow

вторник, 8 октÑÐ±Ñ€Ñ 2013 г., 20:06:51 UTC+4 пользователь Martin Shobe напиÑал:
This is probably pointless, but here goes.



On 10/8/2013 1:38 AM, Vlad from Moscow wrote:
Technically that's a problem with the caller.


When you make "technically" problems for callers it just means that you wrote a bad code and nothing more.
In fact you simply specified incorrect type because class std::string specially declared the corresponding type size_type for such parameters that specify number of elements of a string. But you ignored the interface of the class. This says about your very lower qualification.

And that's a problem because?

You should keep consistent interface among funcrions. This makes it easy touse them and intuitively more clear. Such function will be intershangeablein their usage.


Consider the following simple example. Let assume that you wrote

std::cout << s.erase( 0, n ) << std::endl;

But then you (or somebody else after you) decided that instead of s.erase( 0, n ) there must be shift_left( s, n ).
If you had consistent interface then all you need is to substitute s.erase(0, n ) for shift_left( s, n )

std::cout << shift_left( s, n ) << std::endl;

When you have a consistent interface of functions then it is much easier tosupport programs.

On the implementations I have available, this function

allocated/deallocated memory at most once. For the small n in the

example, it didn't perform any memory allocations.

The original function I pointed out allocates and deallocate memory at least two times irrespective of the value of n. First of all it calls the constructor

std::string( n, ' ' )

that allocates memory.

Secondly operator + again allocates memory to accomodate elements of this temporary object with elements of the original string. And thirdly the memory occupied by the original string has to be substituted for the new one memory.
Still, I do find I prefer the following.



void shift_left(string & s, int n)

{

s.erase(0, n);

s.append(n, ' ');

}



This results in zero allocations regardless of n and I find it clearer.



[snip]


I always wonder the talant of others to substitute a good code for a more bad code.:):)

I already showed how the function shall be defined. The only improvment that could be done is relative the second parameter because usually such a parameter can be assigned std::string::npos that means that all elements of the string must be processed.

So I would rewrite my original solution the following way


std::string & shift_left( std::string &s, int n = 1 )
{
if ( n == std::string::npos ) n = s.size();
return ( s.erase( 0, n ).append( n, ' ' ) );
}
 
V

Vlad from Moscow

вторник, 8 октÑÐ±Ñ€Ñ 2013 г., 20:31:14 UTC+4 пользователь David Brown напиÑал:
You can repeat your misconceptions as much as you want - no one else

will accept them.


If you name definitions in the C++ Standard as misconceptions then it meansonly that you are an idiot. I advice you to read the C++ standard and do not substitute its definitions with your owns.
There is no such language as C/C++.

Nobody said that there is such a language as C/C++. It means simply any of thelanguages either C or C++.:)
 
M

Martin Shobe

вторник, 8 октÑÐ±Ñ€Ñ 2013 г., 20:06:51 UTC+4 пользователь Martin Shobe напиÑал: [snip]
On the implementations I have available, this function

allocated/deallocated memory at most once. For the small n in the

example, it didn't perform any memory allocations.

The original function I pointed out allocates and deallocate memory at least two times irrespective of the value of n. First of all it calls the constructor

std::string( n, ' ' )

that allocates memory.

It may or may not allocate memory. On the implementations I have access
to, the small-string optimization has been implemented, so
std::string(n, ' ') only allocates memory for "large" n.
Secondly operator + again allocates memory to accomodate elements of this temporary object with elements of the original string. And thirdly the memory occupied by the original string has to be substituted for the new one memory.

Those had been optimized away.

[snip]

Martin Shobe
 
V

Vlad from Moscow

вторник, 8 октÑÐ±Ñ€Ñ 2013 г., 22:06:18 UTC+4 пользователь Martin Shobe напиÑал:
вторник, 8 октÑÐ±Ñ€Ñ 2013 г., 20:06:51 UTC+4 пользователь Martin Shobe напиÑал:
[snip]


On the implementations I have available, this function

allocated/deallocated memory at most once. For the small n in the

example, it didn't perform any memory allocations.
The original function I pointed out allocates and deallocate memory at least two times irrespective of the value of n. First of all it calls the constructor
std::string( n, ' ' )
that allocates memory.



It may or may not allocate memory. On the implementations I have access

to, the small-string optimization has been implemented, so

std::string(n, ' ') only allocates memory for "large" n.

The notion of "large" or "small" strings are very conditional. In this concrete case the large string can be considered as any string that has size greater than for example 10 symbols.:)
Try to use expression

std::cout << sizeof( std::string ) << std::endl;

and you will see what the "large" string means in realty.

Those had been optimized away.

it is not guaranteed by the Standard.
[snip]



Martin Shobe
 
R

Rosario1903

In C++ better declare variables as near their first use as possible.

In this case, write e.g. "for( u32 i = 0, ...".

However, as mentioned, it's even better to write just "for( int i = 0, ...".

i'm not agree

i follow the law "declare all that one use at the start of routine
and initialize it near one use it"

cout<<"at start v=["<<v <<"]\n";
ma.shiftd(v, 3);
cout<<"at end ma=["<<ma<<"]\n";

for(i=0;i<12;++i)
{ma.shiftd(ma, 1);
cout<<"at end ma=["<<ma<<"]\n";
}
return 0;

In both C++ and C it's now unnecessary to return 0 from main,
as that's the default.

It has always been the default in C++.

However, many programmers still prefer to indicate the "main"
return value explicitly. For that purpose it can be a good idea
to use the symbolic values EXIT_SUCCESS and EXIT_FAILURE from

As a general comment, since myarray does not take charge of
copying -- it does not declare any copy constructor or assignment
operator -- any use of it that inadvertently invokes copying,
will in general cause the same memory to be deallocated
twice (via the free call in the destructor), invoking
Undefined Behavior, such as e.g. a crash... :-(

yes i make i try of double free: crash

i disagree in something and agree in other
but i think is not important

thank you for the long and good post
 
V

Vlad from Moscow

вторник, 8 октÑÐ±Ñ€Ñ 2013 г., 23:15:36 UTC+4 пользователь Rosario1903 напиÑал:
i'm not agree



i follow the law "declare all that one use at the start of routine

and initialize it near one use it"

There is no such a law.:) Declarations of all used variables in a function at its very beginning only confuse readers because they do not know yet where and how and whether these variables are used.
 
V

Vlad from Moscow

Ñреда, 9 октÑÐ±Ñ€Ñ 2013 г., 0:49:39 UTC+4 пользователь Scott Lurndal напиÑал:
There are coding guidelines at all development shops. Some codify the

source location for declarations such that they are declared at the

beginning of any basic block (e.g. following a '{') instead of interspersing

declarations willy-nilly throughout a function. While C++ allows

willy-nilly declarations, it in no way requires them, and many consider

them to be "confusing", particularly in larger function bodies. When declared

at the start of a block, the maintenance programmer will always know exactly

where to look in a function for the declaration, and many editing tools have

short-cuts to move the cursor to the start of a block ('[[' in vi).



So there is no law either way; it is purely a matter of preference and YPMV.

The the maintenance programmer should look the code where the variables areused. And if he will see numerous variable declarations and he can say nothing what they mean where they used and so on it will be only confused.
I advice you to rewrite your coding guidelines. They are simply a nonsense written by people who understand nothing in programming. Moreover if a function a big enough that it can fit itself one screen you forgot what variables were declared and how they were declared. You will need to scroll scrensforward and back that to see the variable declarations.
So never repeat such ninsenses any more that you wrote for code guidelines.
 
A

alf.p.steinbach

There are coding guidelines at all development shops. Some codify the
source location for declarations such that they are declared at the
beginning of any basic block (e.g. following a '{') instead of interspersing
declarations willy-nilly throughout a function. While C++ allows
willy-nilly declarations, it in no way requires them,

Usually, in good C++ code declarations are neither collected in one place, nor placed willy-nilly, which both are context-independent strategies that disregard the requirements of the code hand.

Rather, in good code the declarations support the code's requirements, and the scope of any variable is reduced to its practical minimum in order to reduce the number of possible interactions and data flows, and also some times in order to get constructor and/or destructor calls properly placed.

The main rationale for using "const" is roughly the same, to reduce complexity by reducing possible interactions that otherwise would have have to be considered, so in code with declarations placed independent of the code requirements I expect to not see much "const" usage either, and v.v.

and many consider
them to be "confusing", particularly in larger function bodies.

A solution is to not have larger function bodies, for whatever measure of "larger" that is problematic.

A 1200-line function can be OK -- I've maintained one such, happily not mine!, it was a systematic list of cases.

An 8-line function can be complete spaghetti.

However, chances are that the larger the function, the less its programmer or maintainers knew about abstraction, so it will much more likely be spaghetti. Which, interacting with the size, creates a maintenance hell. Which in turn causes code to be just copied around, replicating whatever bugs there are and creating more of the original problem, and so on, in a vicious circle.

When declared
at the start of a block, the maintenance programmer will always know exactly
where to look in a function for the declaration,

Presumably you're not talking about introducing a new block every place a new variable is needed.

If you do, however, then I roughly agree, because that /restricts the scope/ of each variable. It can however be overdone. Easily.

But for the case of collecting declarations at the start of a function or at the start of some main block, I think that finding declarations is what the right-click "go to declaration" is for. ;-)

An up-front group of declarations placement thus fails to have an advantagein C++, but it does have a severe disadvantage.

Namely, the grouping of declarations at the start of a main block means that those variables can be changed everywhere in the block, thus wasting eachmaintenance programmer's time by the need for analyzing the data interactions, the way statements in that block can influence each other via the variables.

and many editing tools have
short-cuts to move the cursor to the start of a block ('[[' in vi).

And the good ones even let you go directly to a declaration. ;-)

So there is no law either way; it is purely a matter of preference and YPMV.

Not quite.

In C++ it's some times important where constructors and/or destructors are executed. This can be due to functional requirements, or due to efficiency considerations, or maybe reasons I fail to recall right now (it's late). For these cases it's crucial to restrict the scope of a variable appropriately.

For example, if a constructor can throw, then you might need that declaration inside a try-block if you want to catch the possible exception, or outside the try block if you want to decidedly not catch that possible exception.. Even though this is a rare situation -- with C++ RAII try blocks are generally rare -- it is important for correctness. Similarly for efficiency..


Cheers & hth.,

- Alf
 
R

Rosario1903

Usually, in good C++ code declarations
are neither collected in one place, nor placed willy-nilly,
which both are context-independent strategies that disregard the
requirements of the code hand.
Rather, in good code

good for who?
the declarations support the code's
requirements, and the scope of any variable is reduced
to its practical minimum in order to reduce the number
of possible interactions and data flows,

the error you describe above
[use one varible for function in 2 or more different places of routine
nothing have in common and bad interact of data of that variable]
is in what i know rare [i not remember happen to me]
and in these rare case it is easy to find soon
at first run
and also some times in order to get
constructor and/or destructor calls properly placed.

possible i make error, possible
placed a obj in the start of one routine and use in a loop
it is less memory stressed than insert in the hidden {} of loop
example

f()
{obj k;
for(;;)
{obj w;
operation w and k
}
}

i say if i understand right the k is create one time at start routine
and free at end routine
instead pheraps w is create free
each for() loop passage...

so for what regard machine it is better put it in the beginning of the
routine
The main rationale for using "const" is roughly the same,
to reduce complexity by reducing possible
interactions that otherwise would have
have to be considered, so in code
with declarations placed
independent of the code requirements
I expect to not see much "const" usage either, and v.v.

i not agree, i consider all memory accessible read-write
and if there are mem place where i have to write only one time
i write it... but i never have problem about this

for example the string

"%s\n"

in the format of
printf("%s\n", a)

is conceptually a const string

for the compiler a const string

for the machine a read write string

but even if i possibly can write on that
never happen it

so i think all your tell of how usefull is of const keyword
is void
in pratical case
 
R

Rosario1903

Some codify the
i not agree, i consider all memory accessible read-write
and if there are mem place where i have to write only one time
i write it... but i never have problem about this

for example the string

"%s\n"

in the format of
printf("%s\n", a)

is conceptually a const string

for the compiler a const string

for the machine a read write string

but even if i possibly can write on that
never happen it

so i think all your tell of how usefull is of const keyword
is void
in pratical case

yes happen some time(3-4-5 times in a life) when the program print
strange chars to the screen and the program seg fault...

if that string is const for machine too, it would only seg fault some
micro second first...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,571
Members
45,045
Latest member
DRCM

Latest Threads

Top