dynamically construct an array out of existing strings without new malloc
I want to dynamically allocate an array of strings.
So arr should consist of twenty pointers to the first character of each string.
For simplicity, each string is just the same, stored in base.
The first for loop should now create my array, which seems to work just fine.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int n = 20;
char** arr = malloc( sizeof(char*) + n );
char* base = "abcdefghijklmnopqrstuvwxyz";
for(int i = 0; i < n; i++)
{
*(arr + sizeof(char*) * i) = base;
}
for(int i = 0; i < n; i++)
{
printf("%sn", *(arr + sizeof(char*) * i));
}
}
The seconds for loop creates a segmentation-fault during the second iteration.
c pointers segmentation-fault malloc
add a comment |
I want to dynamically allocate an array of strings.
So arr should consist of twenty pointers to the first character of each string.
For simplicity, each string is just the same, stored in base.
The first for loop should now create my array, which seems to work just fine.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int n = 20;
char** arr = malloc( sizeof(char*) + n );
char* base = "abcdefghijklmnopqrstuvwxyz";
for(int i = 0; i < n; i++)
{
*(arr + sizeof(char*) * i) = base;
}
for(int i = 0; i < n; i++)
{
printf("%sn", *(arr + sizeof(char*) * i));
}
}
The seconds for loop creates a segmentation-fault during the second iteration.
c pointers segmentation-fault malloc
6
sizeof(char*) + n
is a problem
– David Bowling
Nov 21 '18 at 19:43
2
arr[i]
is*(arr + i)
, not*(arr + sizeof(char*) * i)
. You have to use thesizeof
operator only with the functions that operate on raw data viavoid *
pointers. In the pointer arithmetic above, the size of one element is inferred fromarr
's type.
– M Oehm
Nov 21 '18 at 19:45
I hope you don't want to modify the things, yourarr[0 ... 19]
point to.
– Swordfish
Nov 21 '18 at 19:56
sizeof(char*) + n
is actually a paste mistake
– Core
Nov 22 '18 at 9:01
add a comment |
I want to dynamically allocate an array of strings.
So arr should consist of twenty pointers to the first character of each string.
For simplicity, each string is just the same, stored in base.
The first for loop should now create my array, which seems to work just fine.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int n = 20;
char** arr = malloc( sizeof(char*) + n );
char* base = "abcdefghijklmnopqrstuvwxyz";
for(int i = 0; i < n; i++)
{
*(arr + sizeof(char*) * i) = base;
}
for(int i = 0; i < n; i++)
{
printf("%sn", *(arr + sizeof(char*) * i));
}
}
The seconds for loop creates a segmentation-fault during the second iteration.
c pointers segmentation-fault malloc
I want to dynamically allocate an array of strings.
So arr should consist of twenty pointers to the first character of each string.
For simplicity, each string is just the same, stored in base.
The first for loop should now create my array, which seems to work just fine.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int n = 20;
char** arr = malloc( sizeof(char*) + n );
char* base = "abcdefghijklmnopqrstuvwxyz";
for(int i = 0; i < n; i++)
{
*(arr + sizeof(char*) * i) = base;
}
for(int i = 0; i < n; i++)
{
printf("%sn", *(arr + sizeof(char*) * i));
}
}
The seconds for loop creates a segmentation-fault during the second iteration.
c pointers segmentation-fault malloc
c pointers segmentation-fault malloc
asked Nov 21 '18 at 19:41
CoreCore
664
664
6
sizeof(char*) + n
is a problem
– David Bowling
Nov 21 '18 at 19:43
2
arr[i]
is*(arr + i)
, not*(arr + sizeof(char*) * i)
. You have to use thesizeof
operator only with the functions that operate on raw data viavoid *
pointers. In the pointer arithmetic above, the size of one element is inferred fromarr
's type.
– M Oehm
Nov 21 '18 at 19:45
I hope you don't want to modify the things, yourarr[0 ... 19]
point to.
– Swordfish
Nov 21 '18 at 19:56
sizeof(char*) + n
is actually a paste mistake
– Core
Nov 22 '18 at 9:01
add a comment |
6
sizeof(char*) + n
is a problem
– David Bowling
Nov 21 '18 at 19:43
2
arr[i]
is*(arr + i)
, not*(arr + sizeof(char*) * i)
. You have to use thesizeof
operator only with the functions that operate on raw data viavoid *
pointers. In the pointer arithmetic above, the size of one element is inferred fromarr
's type.
– M Oehm
Nov 21 '18 at 19:45
I hope you don't want to modify the things, yourarr[0 ... 19]
point to.
– Swordfish
Nov 21 '18 at 19:56
sizeof(char*) + n
is actually a paste mistake
– Core
Nov 22 '18 at 9:01
6
6
sizeof(char*) + n
is a problem– David Bowling
Nov 21 '18 at 19:43
sizeof(char*) + n
is a problem– David Bowling
Nov 21 '18 at 19:43
2
2
arr[i]
is *(arr + i)
, not *(arr + sizeof(char*) * i)
. You have to use the sizeof
operator only with the functions that operate on raw data via void *
pointers. In the pointer arithmetic above, the size of one element is inferred from arr
's type.– M Oehm
Nov 21 '18 at 19:45
arr[i]
is *(arr + i)
, not *(arr + sizeof(char*) * i)
. You have to use the sizeof
operator only with the functions that operate on raw data via void *
pointers. In the pointer arithmetic above, the size of one element is inferred from arr
's type.– M Oehm
Nov 21 '18 at 19:45
I hope you don't want to modify the things, your
arr[0 ... 19]
point to.– Swordfish
Nov 21 '18 at 19:56
I hope you don't want to modify the things, your
arr[0 ... 19]
point to.– Swordfish
Nov 21 '18 at 19:56
sizeof(char*) + n
is actually a paste mistake– Core
Nov 22 '18 at 9:01
sizeof(char*) + n
is actually a paste mistake– Core
Nov 22 '18 at 9:01
add a comment |
1 Answer
1
active
oldest
votes
Issues
char** arr = malloc( sizeof(char*) + n );
allocates (most likely) 24 bytes which can only store (most likely) sixchar *
.You don't need to try offset the address (
*(arr + sizeof(char*) * i) = base;
) by the base type. The offset is automatically adjusted by thesizeof
the base type.
The following changes must be made:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int n = 20;
char **arr = malloc(sizeof(char *) * n);
char *base = "abcdefghijklmnopqrstuvwxyz";
for(int i = 0; i < n; i++)
arr[i] = base;
for(int i = 0; i < n; i++)
printf("%d: %sn", i, arr[i]);
return 0;
}
The preceding uses array notation. You can also use pointer notation if you'd like. Change arr[i]
to *(arr + i)
.
Output
$ gcc main.c -o main.exe; ./main.exe
0: abcdefghijklmnopqrstuvwxyz
1: abcdefghijklmnopqrstuvwxyz
2: abcdefghijklmnopqrstuvwxyz
3: abcdefghijklmnopqrstuvwxyz
4: abcdefghijklmnopqrstuvwxyz
5: abcdefghijklmnopqrstuvwxyz
6: abcdefghijklmnopqrstuvwxyz
7: abcdefghijklmnopqrstuvwxyz
8: abcdefghijklmnopqrstuvwxyz
9: abcdefghijklmnopqrstuvwxyz
10: abcdefghijklmnopqrstuvwxyz
11: abcdefghijklmnopqrstuvwxyz
12: abcdefghijklmnopqrstuvwxyz
13: abcdefghijklmnopqrstuvwxyz
14: abcdefghijklmnopqrstuvwxyz
15: abcdefghijklmnopqrstuvwxyz
16: abcdefghijklmnopqrstuvwxyz
17: abcdefghijklmnopqrstuvwxyz
18: abcdefghijklmnopqrstuvwxyz
19: abcdefghijklmnopqrstuvwxyz
As recommended by Swordfish you should use the const
qualifier on arr
and base
:
const char **arr = malloc(sizeof(char *) * n);
const char * const base = "abcdefghijklmnopqrstuvwxyz";
In this way:
arr
cannot change (without a warning/error) pointed tochar
s.- Neither the address of
base
nor the pointed tochar
s can be changed (without a warning/error).
Thanks
To Tim Randall for catching a math error.
@TimRandall Thanks for catching my math error.
– Fiddling Bits
Nov 21 '18 at 20:08
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53419444%2fdynamically-construct-an-array-out-of-existing-strings-without-new-malloc%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Issues
char** arr = malloc( sizeof(char*) + n );
allocates (most likely) 24 bytes which can only store (most likely) sixchar *
.You don't need to try offset the address (
*(arr + sizeof(char*) * i) = base;
) by the base type. The offset is automatically adjusted by thesizeof
the base type.
The following changes must be made:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int n = 20;
char **arr = malloc(sizeof(char *) * n);
char *base = "abcdefghijklmnopqrstuvwxyz";
for(int i = 0; i < n; i++)
arr[i] = base;
for(int i = 0; i < n; i++)
printf("%d: %sn", i, arr[i]);
return 0;
}
The preceding uses array notation. You can also use pointer notation if you'd like. Change arr[i]
to *(arr + i)
.
Output
$ gcc main.c -o main.exe; ./main.exe
0: abcdefghijklmnopqrstuvwxyz
1: abcdefghijklmnopqrstuvwxyz
2: abcdefghijklmnopqrstuvwxyz
3: abcdefghijklmnopqrstuvwxyz
4: abcdefghijklmnopqrstuvwxyz
5: abcdefghijklmnopqrstuvwxyz
6: abcdefghijklmnopqrstuvwxyz
7: abcdefghijklmnopqrstuvwxyz
8: abcdefghijklmnopqrstuvwxyz
9: abcdefghijklmnopqrstuvwxyz
10: abcdefghijklmnopqrstuvwxyz
11: abcdefghijklmnopqrstuvwxyz
12: abcdefghijklmnopqrstuvwxyz
13: abcdefghijklmnopqrstuvwxyz
14: abcdefghijklmnopqrstuvwxyz
15: abcdefghijklmnopqrstuvwxyz
16: abcdefghijklmnopqrstuvwxyz
17: abcdefghijklmnopqrstuvwxyz
18: abcdefghijklmnopqrstuvwxyz
19: abcdefghijklmnopqrstuvwxyz
As recommended by Swordfish you should use the const
qualifier on arr
and base
:
const char **arr = malloc(sizeof(char *) * n);
const char * const base = "abcdefghijklmnopqrstuvwxyz";
In this way:
arr
cannot change (without a warning/error) pointed tochar
s.- Neither the address of
base
nor the pointed tochar
s can be changed (without a warning/error).
Thanks
To Tim Randall for catching a math error.
@TimRandall Thanks for catching my math error.
– Fiddling Bits
Nov 21 '18 at 20:08
add a comment |
Issues
char** arr = malloc( sizeof(char*) + n );
allocates (most likely) 24 bytes which can only store (most likely) sixchar *
.You don't need to try offset the address (
*(arr + sizeof(char*) * i) = base;
) by the base type. The offset is automatically adjusted by thesizeof
the base type.
The following changes must be made:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int n = 20;
char **arr = malloc(sizeof(char *) * n);
char *base = "abcdefghijklmnopqrstuvwxyz";
for(int i = 0; i < n; i++)
arr[i] = base;
for(int i = 0; i < n; i++)
printf("%d: %sn", i, arr[i]);
return 0;
}
The preceding uses array notation. You can also use pointer notation if you'd like. Change arr[i]
to *(arr + i)
.
Output
$ gcc main.c -o main.exe; ./main.exe
0: abcdefghijklmnopqrstuvwxyz
1: abcdefghijklmnopqrstuvwxyz
2: abcdefghijklmnopqrstuvwxyz
3: abcdefghijklmnopqrstuvwxyz
4: abcdefghijklmnopqrstuvwxyz
5: abcdefghijklmnopqrstuvwxyz
6: abcdefghijklmnopqrstuvwxyz
7: abcdefghijklmnopqrstuvwxyz
8: abcdefghijklmnopqrstuvwxyz
9: abcdefghijklmnopqrstuvwxyz
10: abcdefghijklmnopqrstuvwxyz
11: abcdefghijklmnopqrstuvwxyz
12: abcdefghijklmnopqrstuvwxyz
13: abcdefghijklmnopqrstuvwxyz
14: abcdefghijklmnopqrstuvwxyz
15: abcdefghijklmnopqrstuvwxyz
16: abcdefghijklmnopqrstuvwxyz
17: abcdefghijklmnopqrstuvwxyz
18: abcdefghijklmnopqrstuvwxyz
19: abcdefghijklmnopqrstuvwxyz
As recommended by Swordfish you should use the const
qualifier on arr
and base
:
const char **arr = malloc(sizeof(char *) * n);
const char * const base = "abcdefghijklmnopqrstuvwxyz";
In this way:
arr
cannot change (without a warning/error) pointed tochar
s.- Neither the address of
base
nor the pointed tochar
s can be changed (without a warning/error).
Thanks
To Tim Randall for catching a math error.
@TimRandall Thanks for catching my math error.
– Fiddling Bits
Nov 21 '18 at 20:08
add a comment |
Issues
char** arr = malloc( sizeof(char*) + n );
allocates (most likely) 24 bytes which can only store (most likely) sixchar *
.You don't need to try offset the address (
*(arr + sizeof(char*) * i) = base;
) by the base type. The offset is automatically adjusted by thesizeof
the base type.
The following changes must be made:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int n = 20;
char **arr = malloc(sizeof(char *) * n);
char *base = "abcdefghijklmnopqrstuvwxyz";
for(int i = 0; i < n; i++)
arr[i] = base;
for(int i = 0; i < n; i++)
printf("%d: %sn", i, arr[i]);
return 0;
}
The preceding uses array notation. You can also use pointer notation if you'd like. Change arr[i]
to *(arr + i)
.
Output
$ gcc main.c -o main.exe; ./main.exe
0: abcdefghijklmnopqrstuvwxyz
1: abcdefghijklmnopqrstuvwxyz
2: abcdefghijklmnopqrstuvwxyz
3: abcdefghijklmnopqrstuvwxyz
4: abcdefghijklmnopqrstuvwxyz
5: abcdefghijklmnopqrstuvwxyz
6: abcdefghijklmnopqrstuvwxyz
7: abcdefghijklmnopqrstuvwxyz
8: abcdefghijklmnopqrstuvwxyz
9: abcdefghijklmnopqrstuvwxyz
10: abcdefghijklmnopqrstuvwxyz
11: abcdefghijklmnopqrstuvwxyz
12: abcdefghijklmnopqrstuvwxyz
13: abcdefghijklmnopqrstuvwxyz
14: abcdefghijklmnopqrstuvwxyz
15: abcdefghijklmnopqrstuvwxyz
16: abcdefghijklmnopqrstuvwxyz
17: abcdefghijklmnopqrstuvwxyz
18: abcdefghijklmnopqrstuvwxyz
19: abcdefghijklmnopqrstuvwxyz
As recommended by Swordfish you should use the const
qualifier on arr
and base
:
const char **arr = malloc(sizeof(char *) * n);
const char * const base = "abcdefghijklmnopqrstuvwxyz";
In this way:
arr
cannot change (without a warning/error) pointed tochar
s.- Neither the address of
base
nor the pointed tochar
s can be changed (without a warning/error).
Thanks
To Tim Randall for catching a math error.
Issues
char** arr = malloc( sizeof(char*) + n );
allocates (most likely) 24 bytes which can only store (most likely) sixchar *
.You don't need to try offset the address (
*(arr + sizeof(char*) * i) = base;
) by the base type. The offset is automatically adjusted by thesizeof
the base type.
The following changes must be made:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int n = 20;
char **arr = malloc(sizeof(char *) * n);
char *base = "abcdefghijklmnopqrstuvwxyz";
for(int i = 0; i < n; i++)
arr[i] = base;
for(int i = 0; i < n; i++)
printf("%d: %sn", i, arr[i]);
return 0;
}
The preceding uses array notation. You can also use pointer notation if you'd like. Change arr[i]
to *(arr + i)
.
Output
$ gcc main.c -o main.exe; ./main.exe
0: abcdefghijklmnopqrstuvwxyz
1: abcdefghijklmnopqrstuvwxyz
2: abcdefghijklmnopqrstuvwxyz
3: abcdefghijklmnopqrstuvwxyz
4: abcdefghijklmnopqrstuvwxyz
5: abcdefghijklmnopqrstuvwxyz
6: abcdefghijklmnopqrstuvwxyz
7: abcdefghijklmnopqrstuvwxyz
8: abcdefghijklmnopqrstuvwxyz
9: abcdefghijklmnopqrstuvwxyz
10: abcdefghijklmnopqrstuvwxyz
11: abcdefghijklmnopqrstuvwxyz
12: abcdefghijklmnopqrstuvwxyz
13: abcdefghijklmnopqrstuvwxyz
14: abcdefghijklmnopqrstuvwxyz
15: abcdefghijklmnopqrstuvwxyz
16: abcdefghijklmnopqrstuvwxyz
17: abcdefghijklmnopqrstuvwxyz
18: abcdefghijklmnopqrstuvwxyz
19: abcdefghijklmnopqrstuvwxyz
As recommended by Swordfish you should use the const
qualifier on arr
and base
:
const char **arr = malloc(sizeof(char *) * n);
const char * const base = "abcdefghijklmnopqrstuvwxyz";
In this way:
arr
cannot change (without a warning/error) pointed tochar
s.- Neither the address of
base
nor the pointed tochar
s can be changed (without a warning/error).
Thanks
To Tim Randall for catching a math error.
edited Nov 21 '18 at 20:05
answered Nov 21 '18 at 19:50
Fiddling BitsFiddling Bits
7,12821939
7,12821939
@TimRandall Thanks for catching my math error.
– Fiddling Bits
Nov 21 '18 at 20:08
add a comment |
@TimRandall Thanks for catching my math error.
– Fiddling Bits
Nov 21 '18 at 20:08
@TimRandall Thanks for catching my math error.
– Fiddling Bits
Nov 21 '18 at 20:08
@TimRandall Thanks for catching my math error.
– Fiddling Bits
Nov 21 '18 at 20:08
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53419444%2fdynamically-construct-an-array-out-of-existing-strings-without-new-malloc%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
6
sizeof(char*) + n
is a problem– David Bowling
Nov 21 '18 at 19:43
2
arr[i]
is*(arr + i)
, not*(arr + sizeof(char*) * i)
. You have to use thesizeof
operator only with the functions that operate on raw data viavoid *
pointers. In the pointer arithmetic above, the size of one element is inferred fromarr
's type.– M Oehm
Nov 21 '18 at 19:45
I hope you don't want to modify the things, your
arr[0 ... 19]
point to.– Swordfish
Nov 21 '18 at 19:56
sizeof(char*) + n
is actually a paste mistake– Core
Nov 22 '18 at 9:01