473,806 Members | 2,259 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Array of value types

Hi.

I have an array of struct.
My question is, if i do:
STRUCT [] a = new STRUCT [0xA];
STRUCT s = new STRUCT();
a [0x0] = s;

since STRUCT is a value type, when assigning element 0 of the STRUCT array
as above,
is the STRUCT then copied to the array, as is the usual case of value types?
I guess it is.

This structure is kind of heavy.
It is as well a managed struct, therefore i cannot use pointers.

My option might be to, rather than assigning the elements,
to use the array directly with indexing(a lot of indexing then):

STRUCT [] a = new STRUCT [0xA];
a [0x0].PROPERTY = 0x0;
Please give me some thoughts about this.

Thank you!

--
Regards,
Dennis JD Myrén
Oslo Kodebureau
Nov 16 '05 #1
10 2070
If this is the actual situation, you can change

STRUCT [] a = new STRUCT [0xA];
STRUCT s = new STRUCT();
a [0x0] = s;

to

STRUCT [] a = new STRUCT [0xA];

as each element of the array will be a struct initialized as if the defauly constructor had run - you can read my blog entry at [1] for the gory details of value type initialization

If this isn't the situation, then yes you will get a copy, but any chance of posting code that is closer to the ral situation so we can advise more concretely

[1] http://staff.develop.com/richardb/we...c-b73640f24314

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog

nntp://news.microsoft. com/microsoft.publi c.dotnet.langua ges.csharp/<BC************ ****@news4.e.ns c.no>

Hi.

I have an array of struct.
My question is, if i do:
STRUCT [] a = new STRUCT [0xA];
STRUCT s = new STRUCT();
a [0x0] = s;

since STRUCT is a value type, when assigning element 0 of the STRUCT array
as above,
is the STRUCT then copied to the array, as is the usual case of value types?
I guess it is.

This structure is kind of heavy.
It is as well a managed struct, therefore i cannot use pointers.

My option might be to, rather than assigning the elements,
to use the array directly with indexing(a lot of indexing then):

STRUCT [] a = new STRUCT [0xA];
a [0x0].PROPERTY = 0x0;
Please give me some thoughts about this.

Thank you!

--
Regards,
Dennis JD Myr?n
Oslo Kodebureau

---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004

[microsoft.publi c.dotnet.langua ges.csharp]
Nov 16 '05 #2
Dennis Myrén <de****@oslokb. no> wrote:
I have an array of struct.
My question is, if i do:
STRUCT [] a = new STRUCT [0xA];
STRUCT s = new STRUCT();
a [0x0] = s;

since STRUCT is a value type, when assigning element 0 of the STRUCT array
as above,
is the STRUCT then copied to the array, as is the usual case of value types?
I guess it is.
Yes.
This structure is kind of heavy.
It is as well a managed struct, therefore i cannot use pointers.
Does it really need to be a structure then?
My option might be to, rather than assigning the elements,
to use the array directly with indexing(a lot of indexing then):

STRUCT [] a = new STRUCT [0xA];
a [0x0].PROPERTY = 0x0;
Yes, you could do that - but if you're going to set any significant
number of properties, wouldn't you be better off with a copy anyway?
Please give me some thoughts about this.


I suggest the first thing to do is check whether you *really* need it
to be a struct rather than a class. I personally very rarely find a use
for defining my own value types.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #3
Thank you for the response, Richard.

I read your blog. Good reading!

--
Regards,
Dennis JD Myrén
Oslo Kodebureau
"Richard Blewett [DevelopMentor]" <ri******@devel op.com> wrote in message
news:uS******** ******@TK2MSFTN GP11.phx.gbl...
If this is the actual situation, you can change

STRUCT [] a = new STRUCT [0xA];
STRUCT s = new STRUCT();
a [0x0] = s;

to

STRUCT [] a = new STRUCT [0xA];

as each element of the array will be a struct initialized as if the
defauly constructor had run - you can read my blog entry at [1] for the
gory details of value type initialization

If this isn't the situation, then yes you will get a copy, but any chance
of posting code that is closer to the ral situation so we can advise more
concretely

[1]
http://staff.develop.com/richardb/we...c-b73640f24314

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog
nntp://news.microsoft. com/microsoft.publi c.dotnet.langua ges.csharp/<BC************ ****@news4.e.ns c.no>

Hi.

I have an array of struct.
My question is, if i do:
STRUCT [] a = new STRUCT [0xA];
STRUCT s = new STRUCT();
a [0x0] = s;

since STRUCT is a value type, when assigning element 0 of the STRUCT array
as above,
is the STRUCT then copied to the array, as is the usual case of value
types?
I guess it is.

This structure is kind of heavy.
It is as well a managed struct, therefore i cannot use pointers.

My option might be to, rather than assigning the elements,
to use the array directly with indexing(a lot of indexing then):

STRUCT [] a = new STRUCT [0xA];
a [0x0].PROPERTY = 0x0;
Please give me some thoughts about this.

Thank you!

--
Regards,
Dennis JD Myr?n
Oslo Kodebureau

---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004

[microsoft.publi c.dotnet.langua ges.csharp]

Nov 16 '05 #4
>Does it really need to be a structure then?
Well, i thought so...
The structure directly represents a chunk of a binary file.
I use:
[ StructLayout( LayoutKind.Sequ ential, Pack = 0x1 ) ]
to explicitly specify that the order is essential.
I use System.Runtime. InteropServices .Marshal class
to create the structure instance from a byte array.
Quite embarrasing, I was sure the StructLayout attribute could only be
applied
to structures, but as i tested making it a class now, it still compiles
without errors.
My option might be to, rather than assigning the elements,
to use the array directly with indexing(a lot of indexing then):

STRUCT [] a = new STRUCT [0xA];
a [0x0].PROPERTY = 0x0;
Yes, you could do that - but if you're going to set any significant
number of properties, wouldn't you be better off with a copy anyway? Just out of interest, where would the breakpoint(arra y index accesses)
be where to rather do a copy than working with array indices
(i can test this by myself though, just if you already know a good answer)?
I suggest the first thing to do is check whether you *really* need it
to be a struct rather than a class. I guess it really does not have to be a structure.
I will go for a class i think.

Thank you Jon for the response on this one.

--
Regards,
Dennis JD Myrén
Oslo Kodebureau
"Jon Skeet [C# MVP]" <sk***@pobox.co m> wrote in message
news:MP******** *************** *@msnews.micros oft.com...
Dennis Myrén <de****@oslokb. no> wrote: I have an array of struct.
My question is, if i do:
STRUCT [] a = new STRUCT [0xA];
STRUCT s = new STRUCT();
a [0x0] = s;

since STRUCT is a value type, when assigning element 0 of the STRUCT array
as above,
is the STRUCT then copied to the array, as is the usual case of value
types?
I guess it is.
Yes.
This structure is kind of heavy.
It is as well a managed struct, therefore i cannot use pointers.
Does it really need to be a structure then?
My option might be to, rather than assigning the elements,
to use the array directly with indexing(a lot of indexing then):

STRUCT [] a = new STRUCT [0xA];
a [0x0].PROPERTY = 0x0;
Yes, you could do that - but if you're going to set any significant
number of properties, wouldn't you be better off with a copy anyway?
Please give me some thoughts about this.


I suggest the first thing to do is check whether you *really* need it
to be a struct rather than a class. I personally very rarely find a use
for defining my own value types.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #5
Dennis Myrén <de****@oslokb. no> wrote:
Does it really need to be a structure then? Well, i thought so...
The structure directly represents a chunk of a binary file.
I use:
[ StructLayout( LayoutKind.Sequ ential, Pack = 0x1 ) ]
to explicitly specify that the order is essential.
I use System.Runtime. InteropServices .Marshal class
to create the structure instance from a byte array.
Quite embarrasing, I was sure the StructLayout attribute could only
be applied to structures, but as i tested making it a class now, it
still compiles without errors.


I wouldn't like to say whether you can still do it, to be honest.
Interop is far from a specialty of mine :(

However, if you have an array of references, you *probably* won't be
able to pass that as an array of that type by interop, because the data
won't be in the right place. Ask in the interop group for more
information.

On the other hand, if you're going to pass all of this via interop
anyway, then it's probably not going to be that much of an issue doing
the in-memory copy to start with.
My option might be to, rather than assigning the elements,
to use the array directly with indexing(a lot of indexing then):

STRUCT [] a = new STRUCT [0xA];
a [0x0].PROPERTY = 0x0;

Yes, you could do that - but if you're going to set any significant
number of properties, wouldn't you be better off with a copy anyway?

Just out of interest, where would the breakpoint(arra y index accesses)
be where to rather do a copy than working with array indices
(i can test this by myself though, just if you already know a good answer)?


I don't know of anything like that - it's just a case of balancing the
convenience of copying the whole structure in one go with the
increasingly marginal performance benefits of using indexing.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #6
Thank you Jon, for helping me out.

By now, i think i will just copy the struct to the array and leave it there.
It works, and after all, that is most important.
And, as you said, convinience is also a factor.
--
Regards,
Dennis JD Myrén
Oslo Kodebureau
"Jon Skeet [C# MVP]" <sk***@pobox.co m> wrote in message
news:MP******** *************** *@msnews.micros oft.com...
Dennis Myrén <de****@oslokb. no> wrote:
Does it really need to be a structure then? Well, i thought so...
The structure directly represents a chunk of a binary file.
I use:
[ StructLayout( LayoutKind.Sequ ential, Pack = 0x1 ) ]
to explicitly specify that the order is essential.
I use System.Runtime. InteropServices .Marshal class
to create the structure instance from a byte array.
Quite embarrasing, I was sure the StructLayout attribute could only
be applied to structures, but as i tested making it a class now, it
still compiles without errors.


I wouldn't like to say whether you can still do it, to be honest.
Interop is far from a specialty of mine :(

However, if you have an array of references, you *probably* won't be
able to pass that as an array of that type by interop, because the data
won't be in the right place. Ask in the interop group for more
information.

On the other hand, if you're going to pass all of this via interop
anyway, then it's probably not going to be that much of an issue doing
the in-memory copy to start with.
My option might be to, rather than assigning the elements,
to use the array directly with indexing(a lot of indexing then):

STRUCT [] a = new STRUCT [0xA];
a [0x0].PROPERTY = 0x0;

Yes, you could do that - but if you're going to set any significant
number of properties, wouldn't you be better off with a copy anyway?

Just out of interest, where would the breakpoint(arra y index accesses)
be where to rather do a copy than working with array indices
(i can test this by myself though, just if you already know a good
answer)?


I don't know of anything like that - it's just a case of balancing the
convenience of copying the whole structure in one go with the
increasingly marginal performance benefits of using indexing.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #7
Just one more question regarding value types;
consider this snippet:
foreach (IFDENTRY e in ifd.entries)
{
....
}

Given that IFDENTRY is a structure, and ifd.entries is a field of type
System.Array
of type IFDENTRY, is this causing a copy as well for each item in the array?

--
Regards,
Dennis JD Myrén
Oslo Kodebureau
"Jon Skeet [C# MVP]" <sk***@pobox.co m> wrote in message
news:MP******** *************** *@msnews.micros oft.com...
Dennis Myrén <de****@oslokb. no> wrote:
Does it really need to be a structure then? Well, i thought so...
The structure directly represents a chunk of a binary file.
I use:
[ StructLayout( LayoutKind.Sequ ential, Pack = 0x1 ) ]
to explicitly specify that the order is essential.
I use System.Runtime. InteropServices .Marshal class
to create the structure instance from a byte array.
Quite embarrasing, I was sure the StructLayout attribute could only
be applied to structures, but as i tested making it a class now, it
still compiles without errors.


I wouldn't like to say whether you can still do it, to be honest.
Interop is far from a specialty of mine :(

However, if you have an array of references, you *probably* won't be
able to pass that as an array of that type by interop, because the data
won't be in the right place. Ask in the interop group for more
information.

On the other hand, if you're going to pass all of this via interop
anyway, then it's probably not going to be that much of an issue doing
the in-memory copy to start with.
My option might be to, rather than assigning the elements,
to use the array directly with indexing(a lot of indexing then):

STRUCT [] a = new STRUCT [0xA];
a [0x0].PROPERTY = 0x0;

Yes, you could do that - but if you're going to set any significant
number of properties, wouldn't you be better off with a copy anyway?

Just out of interest, where would the breakpoint(arra y index accesses)
be where to rather do a copy than working with array indices
(i can test this by myself though, just if you already know a good
answer)?


I don't know of anything like that - it's just a case of balancing the
convenience of copying the whole structure in one go with the
increasingly marginal performance benefits of using indexing.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #8
Yes

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog

nntp://news.microsoft. com/microsoft.publi c.dotnet.langua ges.csharp/<Tr************ ****@news4.e.ns c.no>

Just one more question regarding value types;
consider this snippet:
foreach (IFDENTRY e in ifd.entries)
{
...
}

Given that IFDENTRY is a structure, and ifd.entries is a field of type
System.Array
of type IFDENTRY, is this causing a copy as well for each item in the array?

--
Regards,
Dennis JD Myr?n
Oslo Kodebureau
"Jon Skeet [C# MVP]" <sk***@pobox.co m> wrote in message
news:MP******** *************** *@msnews.micros oft.com...
Dennis Myr?n <de****@oslokb. no> wrote:
Does it really need to be a structure then? Well, i thought so...
The structure directly represents a chunk of a binary file.
I use:
[ StructLayout( LayoutKind.Sequ ential, Pack = 0x1 ) ]
to explicitly specify that the order is essential.
I use System.Runtime. InteropServices .Marshal class
to create the structure instance from a byte array.
Quite embarrasing, I was sure the StructLayout attribute could only
be applied to structures, but as i tested making it a class now, it
still compiles without errors.


I wouldn't like to say whether you can still do it, to be honest.
Interop is far from a specialty of mine :(

However, if you have an array of references, you *probably* won't be
able to pass that as an array of that type by interop, because the data
won't be in the right place. Ask in the interop group for more
information.

On the other hand, if you're going to pass all of this via interop
anyway, then it's probably not going to be that much of an issue doing
the in-memory copy to start with.
My option might be to, rather than assigning the elements,
to use the array directly with indexing(a lot of indexing then):

STRUCT [] a = new STRUCT [0xA];
a [0x0].PROPERTY = 0x0;

Yes, you could do that - but if you're going to set any significant
number of properties, wouldn't you be better off with a copy anyway?

Just out of interest, where would the breakpoint(arra y index accesses)
be where to rather do a copy than working with array indices
(i can test this by myself though, just if you already know a good
answer)?


I don't know of anything like that - it's just a case of balancing the
convenience of copying the whole structure in one go with the
increasingly marginal performance benefits of using indexing.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004

[microsoft.publi c.dotnet.langua ges.csharp]
Nov 16 '05 #9
OK. Thanks Richard.

--
Regards,
Dennis JD Myrén
Oslo Kodebureau
"Richard Blewett [DevelopMentor]" <ri******@devel op.com> wrote in message
news:%2******** ********@TK2MSF TNGP12.phx.gbl. ..
Yes

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog
nntp://news.microsoft. com/microsoft.publi c.dotnet.langua ges.csharp/<Tr************ ****@news4.e.ns c.no>

Just one more question regarding value types;
consider this snippet:
foreach (IFDENTRY e in ifd.entries)
{
...
}

Given that IFDENTRY is a structure, and ifd.entries is a field of type
System.Array
of type IFDENTRY, is this causing a copy as well for each item in the
array?

--
Regards,
Dennis JD Myr?n
Oslo Kodebureau
"Jon Skeet [C# MVP]" <sk***@pobox.co m> wrote in message
news:MP******** *************** *@msnews.micros oft.com...
Dennis Myr?n <de****@oslokb. no> wrote:
Does it really need to be a structure then?

Well, i thought so...
The structure directly represents a chunk of a binary file.
I use:
[ StructLayout( LayoutKind.Sequ ential, Pack = 0x1 ) ]
to explicitly specify that the order is essential.
I use System.Runtime. InteropServices .Marshal class
to create the structure instance from a byte array.
Quite embarrasing, I was sure the StructLayout attribute could only
be applied to structures, but as i tested making it a class now, it
still compiles without errors.


I wouldn't like to say whether you can still do it, to be honest.
Interop is far from a specialty of mine :(

However, if you have an array of references, you *probably* won't be
able to pass that as an array of that type by interop, because the data
won't be in the right place. Ask in the interop group for more
information.

On the other hand, if you're going to pass all of this via interop
anyway, then it's probably not going to be that much of an issue doing
the in-memory copy to start with.
> My option might be to, rather than assigning the elements,
> to use the array directly with indexing(a lot of indexing then):
>
> STRUCT [] a = new STRUCT [0xA];
> a [0x0].PROPERTY = 0x0;

Yes, you could do that - but if you're going to set any significant
number of properties, wouldn't you be better off with a copy anyway?

Just out of interest, where would the breakpoint(arra y index accesses)
be where to rather do a copy than working with array indices
(i can test this by myself though, just if you already know a good
answer)?


I don't know of anything like that - it's just a case of balancing the
convenience of copying the whole structure in one go with the
increasingly marginal performance benefits of using indexing.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004

[microsoft.publi c.dotnet.langua ges.csharp]

Nov 16 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

58
10188
by: jr | last post by:
Sorry for this very dumb question, but I've clearly got a long way to go! Can someone please help me pass an array into a function. Here's a starting point. void TheMainFunc() { // Body of code... TCHAR myArray; DoStuff(myArray);
4
7271
by: Ney André de Mello Zunino | last post by:
Hello. I have a question regarding arrays when used as arguments in function calls. In a situation like the following: void foo(int array) { // ... }
204
13142
by: Alexei A. Frounze | last post by:
Hi all, I have a question regarding the gcc behavior (gcc version 3.3.4). On the following test program it emits a warning: #include <stdio.h> int aInt2 = {0,1,2,4,9,16}; int aInt3 = {0,1,2,4,9};
6
1307
by: Abhishek Srivastava | last post by:
Hello All, In .Net Array is a reference type and an int is a value type. If I create an array of int, then will the items inside the array get boxed? If yes, it will be a terrible overhead. If no, then where will the array elements exist? since items inside the array are value type they have to be on the stack of the executing thread, but the array itself will be on the heap since its a reference type.
32
6529
by: Joe Rattz | last post by:
Hmmm, I wrote the following code. I want an array of bools and I want to intialize them to false. bool bits = new bool; foreach(bool bit in bits) { bit = false; } The compiler complains on the "bit = false;" stating that bit is read-only.
28
2460
by: anonymous | last post by:
I have couple of questions related to array addresses. As they belong to the same block, I am putting them here in one single post. I hope nobody minds: char array; int address; Questions 1: Why cannot I do the following:
30
3226
by: James Daughtry | last post by:
char array; scanf("%19s", &array); I know this is wrong because it's a type mismatch, where scanf expects a pointer to char and gets a pointer to an array of 20 char. I know that question 6.12 of the C FAQ says that it's wrong for that very reason. What I don't know is where the standard tells me conclusively that it's wrong. What I also don't know is somewhere that this type mismatch will break in practice.
12
14460
by: Maxwell2006 | last post by:
Hi, I declared an array like this: string scriptArgs = new string; Can I resize the array later in the code? Thank you, Max
17
2331
by: Ben Bacarisse | last post by:
candide <toto@free.frwrites: These two statements are very different. The first one is just wrong and I am pretty sure you did not mean to suggest that. There is no object in C that is the same as its address. The second one simply depends on a term that is not well-defined. Most people consider the type to be an important part of the notion of
14
1774
by: KK | last post by:
Dear All I have a small problem with using as operator on value type array. Here is an example what I am trying to do. using System; using System.Collections.Generic; using System.Text;
0
9718
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10617
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10364
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
7649
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5545
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5678
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4328
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3849
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3008
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.